diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 9b02eb7f0e..7368548465 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.25 1998/01/19 02:37:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.26 1998/01/20 05:03:30 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -51,6 +51,7 @@ #include "optimizer/clauses.h" #include "utils/palloc.h" #include "utils/mcxt.h" +#include "utils/lsyscache.h" #include "commands/command.h" #include "catalog/index.h" #include "catalog/catname.h" @@ -1207,15 +1208,11 @@ setAtttypmodForCreateTable(TupleDesc tupType, List *targetList, { Var *var; RangeTblEntry *rtentry; - Relation rd; var = (Var *) expr; rtentry = rt_fetch(var->varnoold, rangeTable); - rd = heap_open(rtentry->relid); - /* set length to that defined in relation */ tupType->attrs[varno]->atttypmod = - (*rd->rd_att->attrs[var->varoattno - 1]).atttypmod; - heap_close(rd); + get_atttypmod(rtentry->relid, var->varoattno); } else elog(ERROR, "setAtttypmodForCreateTable: can't get atttypmod for field (for length, etc.)"); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 3f12cbd2c3..d6cc4cd547 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.33 1998/01/19 18:10:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.34 1998/01/20 05:03:40 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -908,7 +908,7 @@ _copySubLink(SubLink *from) newnode->subLinkType = from->subLinkType; newnode->useor = from->useor; Node_Copy(from, newnode, lefthand); - newnode->oper = listCopy(from->oper); + Node_Copy(from, newnode, oper); Node_Copy(from, newnode, subselect); return newnode; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 23f6372866..d7ede89e65 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.24 1998/01/19 18:10:50 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.25 1998/01/20 05:03:49 momjian Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -771,7 +771,7 @@ _outSubLink(StringInfo str, SubLink *node) appendStringInfo(str, " :lefthand "); _outNode(str, node->lefthand); appendStringInfo(str, " :oper "); - _outIntList(str, node->oper); + _outNode(str, node->oper); appendStringInfo(str, " :subselect "); _outNode(str, node->subselect); } diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index 861733cb36..4ac0ee0683 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.13 1998/01/07 15:32:29 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.14 1998/01/20 05:03:54 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -187,15 +187,11 @@ print_expr(Node *expr, List *rtable) break; default: { - Relation r; - rt = rt_fetch(var->varno, rtable); relname = rt->relname; - r = heap_openr(relname); if (rt->refname) relname = rt->refname; /* table renamed */ - attname = attnumAttName(r, var->varattno); - heap_close(r); + attname = get_attname(rt->relid, var->varattno); } break; } diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 297cdec141..2860bad174 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.20 1998/01/19 18:10:52 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.21 1998/01/20 05:03:57 momjian Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -1182,7 +1182,7 @@ _readSubLink() local_node->lefthand = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* eat :oper */ - local_node->oper = toIntList(nodeRead(true)); /* now read it */ + local_node->oper = nodeRead(true); /* now read it */ token = lsptok(NULL, &length); /* eat :subselect */ local_node->subselect = nodeRead(true); /* now read it */ diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 5fc0bb1ac3..077215138f 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.66 1998/01/19 05:06:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.67 1998/01/20 05:04:05 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -67,6 +67,9 @@ parse_analyze(List *pl, ParseState *parentParseState) { pstate = make_parsestate(parentParseState); result->qtrees[i++] = transformStmt(pstate, lfirst(pl)); + if (pstate->p_target_relation != NULL) + heap_close(pstate->p_target_relation); + if (extras != NIL) { result->len += length(extras); @@ -74,13 +77,13 @@ parse_analyze(List *pl, ParseState *parentParseState) while (extras != NIL) { result->qtrees[i++] = transformStmt(pstate, lfirst(extras)); + if (pstate->p_target_relation != NULL) + heap_close(pstate->p_target_relation); extras = lnext(extras); } } extras = NIL; pl = lnext(pl); - if (pstate->p_target_relation != NULL) - heap_close(pstate->p_target_relation); pfree(pstate); } @@ -99,10 +102,10 @@ transformStmt(ParseState *pstate, Node *parseTree) switch (nodeTag(parseTree)) { - /*------------------------ - * Non-optimizable statements - *------------------------ - */ + /*------------------------ + * Non-optimizable statements + *------------------------ + */ case T_CreateStmt: result = transformCreateStmt(pstate, (CreateStmt *) parseTree); break; @@ -159,10 +162,10 @@ transformStmt(ParseState *pstate, Node *parseTree) } break; - /*------------------------ - * Optimizable statements - *------------------------ - */ + /*------------------------ + * Optimizable statements + *------------------------ + */ case T_InsertStmt: result = transformInsertStmt(pstate, (InsertStmt *) parseTree); break; @@ -186,7 +189,7 @@ transformStmt(ParseState *pstate, Node *parseTree) /* * other statments don't require any transformation-- just - * return the original parsetree + * return the original parsetree, yea! */ result = makeNode(Query); result->commandType = CMD_UTILITY; @@ -218,7 +221,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) qry->rtable = pstate->p_rtable; qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname); - /* make sure we don't have aggregates in the where clause */ + qry->hasAggs = pstate->p_hasAggs; if (pstate->p_hasAggs) parseCheckAggregates(pstate, qry); @@ -258,7 +261,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) int ndef = pstate->p_target_relation->rd_att->constr->num_defval; /* - * if stmt->cols == NIL then makeTargetNames returns list of all + * if stmt->cols == NIL then makeTargetNames returns list of all * attrs: have to shorter icolumns list... */ if (stmt->cols == NIL) @@ -315,10 +318,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) /* fix where clause */ qry->qual = transformWhereClause(pstate, stmt->whereClause); - /* check having clause */ - if (stmt->havingClause) - elog(NOTICE, "HAVING not yet supported; ignore clause", NULL); - /* now the range table will not change */ qry->rtable = pstate->p_rtable; qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname); @@ -334,21 +333,21 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) qry->targetList, qry->uniqueFlag); + qry->hasAggs = pstate->p_hasAggs; if (pstate->p_hasAggs) - finalizeAggregates(pstate, qry); + parseCheckAggregates(pstate, qry); + /* The INSERT INTO ... SELECT ... could have a UNION */ qry->unionall = stmt->unionall; /* in child, so unionClause may be false */ qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList); return (Query *) qry; } -/* makeTableName() - * Create a table name from a list of fields. +/* + * makeTableName() + * Create a table name from a list of fields. */ -static char * -makeTableName(void *elem,...); - static char * makeTableName(void *elem,...) { @@ -357,7 +356,7 @@ makeTableName(void *elem,...) char *name; char buf[NAMEDATALEN+1]; - strcpy(buf,""); + buf[0] = '\0'; va_start(args,elem); @@ -368,7 +367,8 @@ makeTableName(void *elem,...) if ((strlen(buf)+strlen(name)) >= (sizeof(buf)-1)) return (NULL); - if (strlen(buf) > 0) strcat(buf,"_"); + if (strlen(buf) > 0) + strcat(buf,"_"); strcat(buf,name); name = va_arg(args,void *); @@ -380,12 +380,9 @@ makeTableName(void *elem,...) strcpy(name,buf); return (name); -} /* makeTableName() */ +} -char * -CreateIndexName(char *tname, char *cname, char *label, List *indices); - -char * +static char * CreateIndexName(char *tname, char *cname, char *label, List *indices) { int pass = 0; @@ -403,17 +400,10 @@ CreateIndexName(char *tname, char *cname, char *label, List *indices) if (iname == NULL) break; -#if PARSEDEBUG -printf("CreateNameIndex- check %s against indices\n",iname); -#endif - ilist = indices; while (ilist != NIL) { index = lfirst(ilist); -#if PARSEDEBUG -printf("CreateNameIndex- compare %s with existing index %s\n",iname,index->idxname); -#endif if (strcasecmp(iname,index->idxname) == 0) break; @@ -431,7 +421,7 @@ printf("CreateNameIndex- compare %s with existing index %s\n",iname,index->idxna } return (iname); -} /* CreateIndexName() */ +} /* * transformCreateStmt - @@ -475,15 +465,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) { case T_ColumnDef: column = (ColumnDef *) element; -#if PARSEDEBUG -printf("transformCreateStmt- found column %s\n",column->colname); -#endif columns = lappend(columns,column); if (column->constraints != NIL) { -#if PARSEDEBUG -printf("transformCreateStmt- found constraint(s) on column %s\n",column->colname); -#endif clist = column->constraints; while (clist != NIL) { @@ -491,9 +475,6 @@ printf("transformCreateStmt- found constraint(s) on column %s\n",column->colname switch (constraint->contype) { case CONSTR_NOTNULL: -#if PARSEDEBUG -printf("transformCreateStmt- found NOT NULL constraint on column %s\n",column->colname); -#endif if (column->is_not_null) elog(ERROR,"CREATE TABLE/NOT NULL already specified" " for %s.%s", stmt->relname, column->colname); @@ -501,9 +482,6 @@ printf("transformCreateStmt- found NOT NULL constraint on column %s\n",column->c break; case CONSTR_DEFAULT: -#if PARSEDEBUG -printf("transformCreateStmt- found DEFAULT clause on column %s\n",column->colname); -#endif if (column->defval != NULL) elog(ERROR,"CREATE TABLE/DEFAULT multiple values specified" " for %s.%s", stmt->relname, column->colname); @@ -511,9 +489,6 @@ printf("transformCreateStmt- found DEFAULT clause on column %s\n",column->colnam break; case CONSTR_PRIMARY: -#if PARSEDEBUG -printf("transformCreateStmt- found PRIMARY KEY clause on column %s\n",column->colname); -#endif if (constraint->name == NULL) constraint->name = makeTableName(stmt->relname, "pkey", NULL); if (constraint->keys == NIL) @@ -522,9 +497,6 @@ printf("transformCreateStmt- found PRIMARY KEY clause on column %s\n",column->co break; case CONSTR_UNIQUE: -#if PARSEDEBUG -printf("transformCreateStmt- found UNIQUE clause on column %s\n",column->colname); -#endif if (constraint->name == NULL) constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL); if (constraint->keys == NIL) @@ -533,9 +505,6 @@ printf("transformCreateStmt- found UNIQUE clause on column %s\n",column->colname break; case CONSTR_CHECK: -#if PARSEDEBUG -printf("transformCreateStmt- found CHECK clause on column %s\n",column->colname); -#endif constraints = lappend(constraints, constraint); if (constraint->name == NULL) constraint->name = makeTableName(stmt->relname, column->colname, NULL); @@ -552,24 +521,15 @@ printf("transformCreateStmt- found CHECK clause on column %s\n",column->colname) case T_Constraint: constraint = (Constraint *) element; -#if PARSEDEBUG -printf("transformCreateStmt- found constraint %s\n", ((constraint->name != NULL)? constraint->name: "(unknown)")); -#endif switch (constraint->contype) { case CONSTR_PRIMARY: -#if PARSEDEBUG -printf("transformCreateStmt- found PRIMARY KEY clause\n"); -#endif if (constraint->name == NULL) constraint->name = makeTableName(stmt->relname, "pkey", NULL); dlist = lappend(dlist, constraint); break; case CONSTR_UNIQUE: -#if PARSEDEBUG -printf("transformCreateStmt- found UNIQUE clause\n"); -#endif #if FALSE if (constraint->name == NULL) constraint->name = makeTableName(stmt->relname, "key", NULL); @@ -578,9 +538,6 @@ printf("transformCreateStmt- found UNIQUE clause\n"); break; case CONSTR_CHECK: -#if PARSEDEBUG -printf("transformCreateStmt- found CHECK clause\n"); -#endif constraints = lappend(constraints, constraint); break; @@ -620,11 +577,6 @@ printf("transformCreateStmt- found CHECK clause\n"); if (nodeTag(constraint) != T_Constraint) elog(ERROR,"parser: internal error; unrecognized deferred node",NULL); -#if PARSEDEBUG -printf("transformCreateStmt- found deferred constraint %s\n", - ((constraint->name != NULL)? constraint->name: "(unknown)")); -#endif - if (constraint->contype == CONSTR_PRIMARY) if (have_pkey) elog(ERROR,"CREATE TABLE/PRIMARY KEY multiple primary keys" @@ -634,11 +586,6 @@ printf("transformCreateStmt- found deferred constraint %s\n", else if (constraint->contype != CONSTR_UNIQUE) elog(ERROR,"parser: internal error; unrecognized deferred constraint",NULL); -#if PARSEDEBUG -printf("transformCreateStmt- found deferred %s clause\n", - (constraint->contype == CONSTR_PRIMARY? "PRIMARY KEY": "UNIQUE")); -#endif - index = makeNode(IndexStmt); index->unique = TRUE; @@ -665,17 +612,11 @@ printf("transformCreateStmt- found deferred %s clause\n", while (keys != NIL) { key = lfirst(keys); -#if PARSEDEBUG -printf("transformCreateStmt- check key %s for column match\n", key->name); -#endif columns = stmt->tableElts; column = NULL; while (columns != NIL) { column = lfirst(columns); -#if PARSEDEBUG -printf("transformCreateStmt- check column %s for key match\n", column->colname); -#endif if (strcasecmp(column->colname,key->name) == 0) break; else column = NULL; columns = lnext(columns); @@ -684,12 +625,7 @@ printf("transformCreateStmt- check column %s for key match\n", column->colname); elog(ERROR,"parser: column '%s' in key does not exist",key->name); if (constraint->contype == CONSTR_PRIMARY) - { -#if PARSEDEBUG -printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname); -#endif column->is_not_null = TRUE; - } iparam = makeNode(IndexElem); iparam->name = strcpy(palloc(strlen(column->colname)+1), column->colname); iparam->args = NIL; @@ -719,7 +655,7 @@ printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname); extras = ilist; return q; -} /* transformCreateStmt() */ +} /* * transformIndexStmt - @@ -830,17 +766,10 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) qry->into = stmt->into; qry->isPortal = FALSE; - /* fix the target list */ qry->targetList = transformTargetList(pstate, stmt->targetList); - /* fix where clause */ qry->qual = transformWhereClause(pstate, stmt->whereClause); - /* check having clause */ - if (stmt->havingClause) - elog(NOTICE, "HAVING not yet supported; ignore clause", NULL); - - /* fix order clause */ qry->sortClause = transformSortClause(pstate, stmt->sortClause, NIL, @@ -852,8 +781,9 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) qry->targetList); qry->rtable = pstate->p_rtable; + qry->hasAggs = pstate->p_hasAggs; if (pstate->p_hasAggs) - finalizeAggregates(pstate, qry); + parseCheckAggregates(pstate, qry); qry->unionall = stmt->unionall; /* in child, so unionClause may be false */ qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList); @@ -880,19 +810,15 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) */ makeRangeTable(pstate, stmt->relname, stmt->fromClause); - /* fix the target list */ qry->targetList = transformTargetList(pstate, stmt->targetList); - /* fix where clause */ qry->qual = transformWhereClause(pstate, stmt->whereClause); qry->rtable = pstate->p_rtable; + qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname); - if (pstate->p_hasAggs) - finalizeAggregates(pstate, qry); - - /* make sure we don't have aggregates in the where clause */ + qry->hasAggs = pstate->p_hasAggs; if (pstate->p_hasAggs) parseCheckAggregates(pstate, qry); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 244c834568..e259fbeca8 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.94 1998/01/19 05:06:15 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.95 1998/01/20 05:04:07 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -278,7 +278,7 @@ Oid param_type(int t); /* used in parse_expr.c */ INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LISTEN, LOAD, LOCATION, MERGE, MOVE, NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL, - RECIPE, RENAME, REPLACE, RESET, RETRIEVE, RETURNS, RULE, + RECIPE, RENAME, REPLACE, RESET, RETURNS, RULE, SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED, VACUUM, VERBOSE, VERSION @@ -2446,7 +2446,11 @@ groupby: ColId } ; -having_clause: HAVING a_expr { $$ = $2; } +having_clause: HAVING a_expr + { + elog(NOTICE, "HAVING not yet supported; ignore clause"); + $$ = $2; + } | /*EMPTY*/ { $$ = NULL; } ; @@ -3637,7 +3641,7 @@ res_target_el: ColId opt_indirection '=' a_expr_or_null /* ** target list for select. -** should get rid of the other but is still needed by the defunct retrieve into +** should get rid of the other but is still needed by the defunct select into ** and update (uses a subset) */ res_target_list2: res_target_list2 ',' res_target_el2 diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 3049689aa1..904d71a43f 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.30 1998/01/19 05:06:16 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.31 1998/01/20 05:04:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -167,7 +167,6 @@ static ScanKeyword ScanKeywords[] = { {"rename", RENAME}, {"replace", REPLACE}, {"reset", RESET}, - {"retrieve", RETRIEVE}, {"returns", RETURNS}, {"revoke", REVOKE}, {"right", RIGHT}, @@ -235,22 +234,3 @@ ScanKeywordLookup(char *text) return (NULL); } - -#ifdef NOT_USED -char * -AtomValueGetString(int atomval) -{ - ScanKeyword *low = &ScanKeywords[0]; - ScanKeyword *high = endof(ScanKeywords) - 1; - int keyword_list_length = (high - low); - int i; - - for (i = 0; i < keyword_list_length; i++) - if (ScanKeywords[i].value == atomval) - return (ScanKeywords[i].name); - - elog(ERROR, "AtomGetString called with bogus atom # : %d", atomval); - return (NULL); -} - -#endif diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 15413ecb73..8474d2be41 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.7 1998/01/15 18:59:59 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.8 1998/01/20 05:04:11 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -34,19 +34,6 @@ static bool contain_agg_clause(Node *clause); static bool exprIsAggOrGroupCol(Node *expr, List *groupClause); static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause); -/* - * finalizeAggregates - - * fill in hasAggs from pstate. Also checks to make sure that aggregates - * are used in the proper place. - */ -void -finalizeAggregates(ParseState *pstate, Query *qry) -{ - parseCheckAggregates(pstate, qry); - - qry->hasAggs = pstate->p_hasAggs; -} - /* * contain_agg_clause-- * Recursively find aggreg nodes from a clause. @@ -247,9 +234,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype, ObjectIdGetDatum(basetype), 0, 0); if (!HeapTupleIsValid(theAggTuple)) - { elog(ERROR, "aggregate %s does not exist", aggname); - } /* * We do a major hack for count(*) here. @@ -267,7 +252,10 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype, * range table entry, and pick the first column from the table. * We set a flag to count nulls, because we could have nulls in * that column. - */ + * + * It's an ugly job, but someone has to do it. + * bjm 1998/1/18 + */ if (nodeTag(lfirst(target)) == T_Const) { @@ -275,7 +263,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype, if (con->consttype == UNKNOWNOID && VARSIZE(con->constvalue) == VARHDRSZ) { - Attr *attr = makeNode(Attr); + Attr *attr = makeNode(Attr); List *rtable, *rlist; RangeTblEntry *first_valid_rte; @@ -295,7 +283,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype, if (!rte->inFromCl && rte != pstate->p_target_rangetblentry) continue; - first_valid_rte =rte; + first_valid_rte = rte; break; } if (first_valid_rte == NULL) @@ -314,7 +302,6 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype, fintype = aggform->aggfinaltype; xfn1 = aggform->aggtransfn1; - /* only aggregates with transfn1 need a base type */ if (OidIsValid(xfn1)) { @@ -374,4 +361,3 @@ agg_error(char *caller, char *aggname, Oid basetypeID) typeidTypeName(basetypeID)); } } - diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 71aaf24423..115b8c153d 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.9 1998/01/19 05:06:17 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.10 1998/01/20 05:04:12 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -53,7 +53,6 @@ makeRangeTable(ParseState *pstate, char *relname, List *frmList) pstate->p_target_rangetblentry = rte; Assert(pstate->p_target_relation == NULL); pstate->p_target_relation = heap_open(rte->relid); - Assert(pstate->p_target_relation != NULL); /* will close relation later */ } @@ -68,11 +67,12 @@ transformWhereClause(ParseState *pstate, Node *a_expr) Node *qual; if (a_expr == NULL) - return (Node *) NULL; /* no qualifiers */ + return NULL; /* no qualifiers */ pstate->p_in_where_clause = true; qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST); pstate->p_in_where_clause = false; + if (exprType(qual) != BOOLOID) { elog(ERROR, @@ -88,7 +88,7 @@ transformWhereClause(ParseState *pstate, Node *a_expr) * range table. The range table may grow as we transform the expressions * in the target list. (Note that this happens because in POSTQUEL, we * allow references to relations not specified in the from-clause. We - * also allow that in our POST-SQL) + * also allow now as an extension.) * */ static void @@ -148,11 +148,6 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist) char *resname = resnode->resname; int test_rtable_pos = var->varno; -#ifdef PARSEDEBUG - printf("find_targetlist_entry- target name is %s, position %d, resno %d\n", - (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno); -#endif - if (!sortgroupby->name) { if (sortgroupby->resno == ++target_pos) @@ -345,10 +340,8 @@ transformSortClause(ParseState *pstate, break; } if (i == NIL) - { elog(ERROR, "The field specified in the UNIQUE ON clause is not in the targetlist"); - } - s = sortlist; + foreach(s, sortlist) { SortClause *sortcl = lfirst(s); diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index e321a8517e..ef42a61fe2 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.10 1998/01/19 18:10:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.11 1998/01/20 05:04:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -55,8 +55,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) Attr *att = (Attr *) expr; Node *temp; - /* what if att.attrs == "*"?? */ - temp = handleNestedDots(pstate, att, &pstate->p_last_resno, + /* what if att.attrs == "*"? */ + temp = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno, precedence); if (att->indirection != NIL) { @@ -77,11 +77,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) if (exprType(lexpr) != INT4OID) elog(ERROR, "array index expressions must be int4's"); } -#if 0 - pfree(ai->uidx); - if (ai->lidx != NULL) - pfree(ai->lidx); -#endif ai->lidx = lexpr; ai->uidx = uexpr; @@ -106,13 +101,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) Value *val = &con->val; if (con->typename != NULL) - { - result = parser_typecast(val, con->typename, -1); - } + result = parser_typecast(val, con->typename, 0); else - { result = (Node *) make_const(val); - } break; } case T_ParamNo: @@ -125,9 +116,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) paramno = pno->number; toid = param_type(paramno); if (!OidIsValid(toid)) - { elog(ERROR, "Parameter '$%d' is out of range", paramno); - } param = makeNode(Param); param->paramkind = PARAM_NUM; param->paramid = (AttrNumber) paramno; @@ -156,7 +145,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) { Node *lexpr = transformExpr(pstate, a->lexpr, precedence); - result = ParseFunc(pstate, + result = ParseFuncOrColumn(pstate, "nullvalue", lcons(lexpr, NIL), &pstate->p_last_resno, precedence); @@ -166,7 +155,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) { Node *lexpr = transformExpr(pstate, a->lexpr, precedence); - result = ParseFunc(pstate, + result = ParseFuncOrColumn(pstate, "nonnullvalue", lcons(lexpr, NIL), &pstate->p_last_resno, precedence); @@ -229,7 +218,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) } case T_Ident: { - /* * look for a column name or a relation name (the default * behavior) @@ -245,7 +233,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) /* transform the list of arguments */ foreach(args, fn->args) lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence); - result = ParseFunc(pstate, + result = ParseFuncOrColumn(pstate, fn->funcname, fn->args, &pstate->p_last_resno, precedence); break; @@ -272,22 +260,21 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) { char *op = lfirst(sublink->oper); List *left_expr = sublink->lefthand; - List *right_expr = subselect->targetList; - List *elist; - + List *right_expr = subselect->targetList; + List *elist; + sublink->oper = NIL; - foreach(elist, left_expr) - { + foreach(elist, left_expr) + { Node *lexpr = lfirst(elist); - Node *rexpr = lfirst(right_expr); - TargetEntry *tent = (TargetEntry *)rexpr; - Expr *op_expr; - - op_expr = make_op(op, lexpr, tent->expr); - sublink->oper = lappendi(sublink->oper, - ((Oper *)op_expr->oper)->opno); - right_expr = lnext(right_expr); - } + Node *rexpr = lfirst(right_expr); + TargetEntry *tent = (TargetEntry *)rexpr; + Expr *op_expr; + + op_expr = make_op(op, lexpr, tent->expr); + sublink->oper = lappend(sublink->oper, op_expr->oper); + right_expr = lnext(right_expr); + } result = (Node *) expr; } break; @@ -320,7 +307,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence) att->relname = rte->refname; att->attrs = lcons(makeString(ident->name), NIL); column_result = - (Node *) handleNestedDots(pstate, att, &pstate->p_last_resno, + (Node *) ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno, precedence); } @@ -403,51 +390,6 @@ exprType(Node *expr) return type; } -/* - ** HandleNestedDots -- - ** Given a nested dot expression (i.e. (relation func ... attr), build up - ** a tree with of Iter and Func nodes. - */ -Node * -handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno, int precedence) -{ - List *mutator_iter; - Node *retval = NULL; - - if (attr->paramNo != NULL) - { - Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST); - - retval = - ParseFunc(pstate, strVal(lfirst(attr->attrs)), - lcons(param, NIL), - curr_resno, - precedence); - } - else - { - Ident *ident = makeNode(Ident); - - ident->name = attr->relname; - ident->isRel = TRUE; - retval = - ParseFunc(pstate, strVal(lfirst(attr->attrs)), - lcons(ident, NIL), - curr_resno, - precedence); - } - - foreach(mutator_iter, lnext(attr->attrs)) - { - retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)), - lcons(retval, NIL), - curr_resno, - precedence); - } - - return (retval); -} - static Node * parser_typecast(Value *expr, TypeName *typename, int atttypmod) { @@ -489,69 +431,10 @@ parser_typecast(Value *expr, TypeName *typename, int atttypmod) len = typeLen(tp); -#if 0 /* fix me */ - switch (CInteger(lfirst(expr))) - { - case INT4OID: /* int4 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string, "%d", ((Const *) lnext(expr))->constvalue); - break; - - case NAMEOID: /* char16 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string, "%s", ((Const *) lnext(expr))->constvalue); - break; - - case CHAROID: /* char */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string, "%c", ((Const) lnext(expr))->constvalue); - break; - - case FLOAT8OID: /* float8 */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string, "%f", ((Const) lnext(expr))->constvalue); - break; - - case CASHOID: /* money */ - const_string = (char *) palloc(256); - string_palloced = true; - sprintf(const_string, "%d", - (int) ((Const *) expr)->constvalue); - break; - - case TEXTOID: /* text */ - const_string = DatumGetPointer(((Const) lnext(expr))->constvalue); - const_string = (char *) textout((struct varlena *) const_string); - break; - - case UNKNOWNOID: /* unknown */ - const_string = DatumGetPointer(((Const) lnext(expr))->constvalue); - const_string = (char *) textout((struct varlena *) const_string); - break; - - default: - elog(ERROR, "unknown type %d", CInteger(lfirst(expr))); - } -#endif - cp = stringTypeString(tp, const_string, atttypmod); if (!typeByVal(tp)) - { -/* - if (len >= 0 && len != PSIZE(cp)) { - char *pp; - pp = (char *) palloc(len); - memmove(pp, cp, len); - cp = pp; - } -*/ lcp = PointerGetDatum(cp); - } else { switch (len) @@ -676,17 +559,7 @@ parser_typecast2(Node *expr, Oid exprType, Type tp, int atttypmod) cp = stringTypeString(tp, const_string, atttypmod); if (!typeByVal(tp)) - { -/* - if (len >= 0 && len != PSIZE(cp)) { - char *pp; - pp = (char *) palloc(len); - memmove(pp, cp, len); - cp = pp; - } -*/ lcp = PointerGetDatum(cp); - } else { switch (len) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 76782fc7ad..e8466fa626 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.6 1998/01/15 19:00:02 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.7 1998/01/20 05:04:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -34,6 +34,7 @@ #include "parser/parse_func.h" #include "parser/parse_node.h" #include "parser/parse_relation.h" +#include "parser/parse_target.h" #include "parser/parse_type.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" @@ -82,12 +83,55 @@ typedef struct _SuperQE Oid sqe_relid; } SuperQE; +/* + ** ParseNestedFuncOrColumn -- + ** Given a nested dot expression (i.e. (relation func ... attr), build up + ** a tree with of Iter and Func nodes. + */ +Node * +ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, int *curr_resno, int precedence) +{ + List *mutator_iter; + Node *retval = NULL; + + if (attr->paramNo != NULL) + { + Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST); + + retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)), + lcons(param, NIL), + curr_resno, + precedence); + } + else + { + Ident *ident = makeNode(Ident); + + ident->name = attr->relname; + ident->isRel = TRUE; + retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)), + lcons(ident, NIL), + curr_resno, + precedence); + } + + /* Do more attributes follow this one? */ + foreach(mutator_iter, lnext(attr->attrs)) + { + retval = ParseFuncOrColumn(pstate, strVal(lfirst(mutator_iter)), + lcons(retval, NIL), + curr_resno, + precedence); + } + + return (retval); +} + /* * parse function */ - Node * -ParseFunc(ParseState *pstate, char *funcname, List *fargs, +ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, int *curr_resno, int precedence) { Oid rettype = (Oid) 0; @@ -122,9 +166,10 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, * that argument is a relation, param, or PQ function returning a * complex * type, then the function could be a projection. */ + /* We only have one parameter */ if (length(fargs) == 1) { - + /* Is is a plain Relation name from the parser? */ if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel) { RangeTblEntry *rte; @@ -150,8 +195,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, { Oid dummyTypeId; - return - ((Node *) make_var(pstate, + return ((Node *) make_var(pstate, refname, funcname, &dummyTypeId)); @@ -210,7 +254,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, Oid basetype; /* - * the aggregate count is a special case, ignore its base + * the aggregate COUNT is a special case, ignore its base * type. Treat it as zero */ if (strcmp(funcname, "count") == 0) @@ -280,9 +324,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, */ if (exprType(pair) == UNKNOWNOID && !IsA(pair, Const)) - { - elog(ERROR, "ParseFunc: no function named '%s' that takes in an unknown type as argument #%d", funcname, nargs); - } + elog(ERROR, "ParseFuncOrColumn: no function named '%s' that takes in an unknown type as argument #%d", funcname, nargs); else toid = exprType(pair); } @@ -504,10 +546,8 @@ func_get_candidates(char *funcname, int nargs) palloc(8 * sizeof(Oid)); MemSet(current_candidate->args, 0, 8 * sizeof(Oid)); for (i = 0; i < nargs; i++) - { current_candidate->args[i] = pgProcP->proargtypes[i]; - } current_candidate->next = candidates; candidates = current_candidate; @@ -1009,7 +1049,7 @@ make_arguments(int nargs, /* ** setup_tlist -- ** Build a tlist that says which attribute to project to. - ** This routine is called by ParseFunc() to set up a target list + ** This routine is called by ParseFuncOrColumn() to set up a target list ** on a tuple parameter or return value. Due to a bug in 4.0, ** it's not possible to refer to system attributes in this case. */ @@ -1264,6 +1304,3 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes) elog(ERROR, "%s: function %s(%s) does not exist", caller, funcname, p); } - - - diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 03bc54d531..ffcafcedb1 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.8 1998/01/19 05:06:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.9 1998/01/20 05:04:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/syscache.h" +#include "utils/lsyscache.h" static void disallow_setop(char *op, Type optype, Node *operand); static Node *make_operand(char *opname, @@ -228,17 +229,11 @@ make_op(char *opname, Node *ltree, Node *rtree) result->oper = (Node *) newop; if (!left) - { result->args = lcons(right, NIL); - } else if (!right) - { result->args = lcons(left, NIL); - } else - { result->args = lcons(left, lcons(right, NIL)); - } return result; } @@ -250,7 +245,6 @@ make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id) int vnum, attid; Oid vartypeid; - Relation rd; RangeTblEntry *rte; rte = refnameRangeTableEntry(pstate->p_rtable, refname); @@ -259,16 +253,15 @@ make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id) vnum = refnameRangeTablePosn(pstate->p_rtable, refname); - rd = heap_open(rte->relid); - - attid = attnameAttNum(rd, attrname); /* could elog(ERROR) */ - vartypeid = attnumTypeId(rd, attid); + attid = get_attnum(rte->relid, attrname); + if (attid == InvalidAttrNumber) + elog(ERROR, "Relation %s does not have attribute %s", + rte->relname, attrname); + vartypeid = get_atttype(rte->relid, attid); varnode = makeVar(vnum, attid, vartypeid, vnum, attid); - - heap_close(rd); - *type_id = vartypeid; + return varnode; } @@ -311,10 +304,8 @@ make_array_ref(Node *expr, type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple); if (type_struct_array->typelem == InvalidOid) - { elog(ERROR, "make_array_ref: type %s is not an array", (Name) &(type_struct_array->typname.data[0])); - } /* get the type tuple for the element type */ type_tuple = SearchSysCacheTuple(TYPOID, @@ -331,13 +322,11 @@ make_array_ref(Node *expr, A_Indices *ind = lfirst(indirection); if (ind->lidx) - { - /* * XXX assumes all lower indices non null in this case */ lowerIndexpr = lappend(lowerIndexpr, ind->lidx); - } + upperIndexpr = lappend(upperIndexpr, ind->uidx); indirection = lnext(indirection); } @@ -393,10 +382,8 @@ make_array_set(Expr *target_expr, type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple); if (type_struct_array->typelem == InvalidOid) - { elog(ERROR, "make_array_ref: type %s is not an array", (Name) &(type_struct_array->typname.data[0])); - } /* get the type tuple for the element type */ type_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(type_struct_array->typelem), diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index 253fed7ced..ded519a72b 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.7 1998/01/16 23:20:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.8 1998/01/20 05:04:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -540,23 +540,6 @@ left_oper(char *op, Oid arg) return ((Operator) tup); } -/* Given a typename and value, returns the ascii form of the value */ - -#ifdef NOT_USED -char * -outstr(char *typename, /* Name of type of value */ - char *value) /* Could be of any type */ -{ - TypeTupleForm tp; - Oid op; - - tp = (TypeTupleForm) GETSTRUCT(type(typename)); - op = tp->typoutput; - return ((char *) fmgr(op, value)); -} - -#endif - /* * Give a somewhat useful error message when the operator for two types * is not found. @@ -598,4 +581,3 @@ op_error(char *op, Oid arg1, Oid arg2) "\n\tor you will have to define the operator using CREATE OPERATOR", op, typeTypeName(tp1), typeTypeName(tp2)); } - diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 692b1eb116..5009b0326b 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.6 1998/01/16 23:20:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.7 1998/01/20 05:04:24 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -97,7 +97,7 @@ refnameRangeTablePosn(List *rtable, char *refname) return index; index++; } - return (0); + return 0; } /* @@ -162,10 +162,12 @@ addRangeTableEntry(ParseState *pstate, relation = heap_openr(relname); if (relation == NULL) - { elog(ERROR, "%s: %s", - relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]); - } + relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]); + + rte->relid = RelationGetRelationId(relation); + + heap_close(relation); /* * Flags - zero or more from inheritance,union,version or @@ -175,8 +177,6 @@ addRangeTableEntry(ParseState *pstate, rte->inh = inh; /* RelOID */ - rte->relid = RelationGetRelationId(relation); - rte->inFromCl = inFromCl; /* @@ -185,8 +185,6 @@ addRangeTableEntry(ParseState *pstate, if (pstate != NULL) pstate->p_rtable = lappend(pstate->p_rtable, rte); - heap_close(relation); - return rte; } @@ -215,11 +213,9 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno) rdesc = heap_open(rte->relid); if (rdesc == NULL) - { elog(ERROR, "Unable to expand all -- heap_open failed on %s", rte->refname); - return NIL; - } + maxattrs = RelationGetNumberOfAttributes(rdesc); for (varattno = 0; varattno <= maxattrs - 1; varattno++) @@ -256,10 +252,17 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno) } heap_close(rdesc); + return (te_head); } -/* given relation and att name, return id of variable */ +/* + * given relation and att name, return id of variable + * + * This should only be used if the relation is already + * heap_open()'ed. Use the cache version get_attnum() + * for access to non-opened relations. + */ int attnameAttNum(Relation rd, char *a) { @@ -279,10 +282,15 @@ attnameAttNum(Relation rd, char *a) return 0; /* lint */ } -/* Given range variable, return whether attribute of this name +/* + * Given range variable, return whether attribute of this name * is a set. * NOTE the ASSUMPTION here that no system attributes are, or ever * will be, sets. + * + * This should only be used if the relation is already + * heap_open()'ed. Use the cache version get_attisset() + * for access to non-opened relations. */ bool attnameIsSet(Relation rd, char *name) @@ -300,46 +308,11 @@ attnameIsSet(Relation rd, char *name) return (get_attisset(rd->rd_id, name)); } -/*------------- - * given an attribute number and a relation, return its relation name +/* + * This should only be used if the relation is already + * heap_open()'ed. Use the cache version + * for access to non-opened relations. */ -char * -attnumAttName(Relation rd, int attrno) -{ - char *name; - int i; - - if (attrno < 0) - { - for (i = 0; i < SPECIALS; i++) - { - if (special_attr[i].code == attrno) - { - name = special_attr[i].field; - return (name); - } - } - elog(ERROR, "Illegal attr no %d for relation %s", - attrno, RelationGetRelationName(rd)); - } - else if (attrno >= 1 && attrno <= RelationGetNumberOfAttributes(rd)) - { - name = (rd->rd_att->attrs[attrno - 1]->attname).data; - return (name); - } - else - { - elog(ERROR, "Illegal attr no %d for relation %s", - attrno, RelationGetRelationName(rd)); - } - - /* - * Shouldn't get here, but we want lint to be happy... - */ - - return (NULL); -} - int attnumAttNelems(Relation rd, int attid) { @@ -347,7 +320,11 @@ attnumAttNelems(Relation rd, int attid) } /* given attribute id, return type of that attribute */ -/* XXX Special case for pseudo-attributes is a hack */ +/* + * This should only be used if the relation is already + * heap_open()'ed. Use the cache version get_atttype() + * for access to non-opened relations. + */ Oid attnumTypeId(Relation rd, int attid) { @@ -398,7 +375,6 @@ checkTargetTypes(ParseState *pstate, char *target_colname, attrtype_target; int resdomno_id, resdomno_target; - Relation rd; RangeTblEntry *rte; if (target_colname == NULL || colname == NULL) @@ -418,10 +394,8 @@ checkTargetTypes(ParseState *pstate, char *target_colname, if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry) elog(ERROR, "%s not available in this context", colname); */ - rd = heap_open(rte->relid); - - resdomno_id = attnameAttNum(rd, colname); - attrtype_id = attnumTypeId(rd, resdomno_id); + resdomno_id = get_attnum(rte->relid, colname); + attrtype_id = get_atttype(rte->relid, resdomno_id); resdomno_target = attnameAttNum(pstate->p_target_relation, target_colname); attrtype_target = attnumTypeId(pstate->p_target_relation, resdomno_target); @@ -431,15 +405,14 @@ checkTargetTypes(ParseState *pstate, char *target_colname, colname, target_colname); if (attrtype_id == BPCHAROID && - rd->rd_att->attrs[resdomno_id - 1]->atttypmod != - pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->atttypmod) + get_atttypmod(rte->relid, resdomno_id) != + get_atttype(pstate->p_target_relation->rd_id, resdomno_target)) elog(ERROR, "Length of %s is longer than length of target column %s", colname, target_colname); if (attrtype_id == VARCHAROID && - rd->rd_att->attrs[resdomno_id - 1]->atttypmod > - pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->atttypmod) + get_atttypmod(rte->relid, resdomno_id) > + get_atttype(pstate->p_target_relation->rd_id, resdomno_target)) elog(ERROR, "Length of %s is longer than length of target column %s", colname, target_colname); - heap_close(rd); } diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 895411aa1d..4aa961ed45 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.6 1998/01/16 23:20:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.7 1998/01/20 05:04:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #include "nodes/makefuncs.h" #include "nodes/primnodes.h" #include "parser/parse_expr.h" +#include "parser/parse_func.h" #include "parser/parse_node.h" #include "parser/parse_relation.h" #include "parser/parse_target.h" @@ -255,7 +256,7 @@ transformTargetList(ParseState *pstate, List *targetlist) * Target item is fully specified: ie. * relation.attribute */ - result = handleNestedDots(pstate, att, &pstate->p_last_resno,EXPR_COLUMN_FIRST); + result = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno,EXPR_COLUMN_FIRST); handleTargetColname(pstate, &res->name, att->relname, attrname); if (att->indirection != NIL) { @@ -345,13 +346,12 @@ make_targetlist_expr(ParseState *pstate, else type_len = typeLen(typeidType(type_id)); - /* I have no idea what the following does! */ - /* It appears to process target columns that will be receiving results */ + /* Processes target columns that will be receiving results */ if (pstate->p_is_insert || pstate->p_is_update) { /* - * append or replace query -- append, replace work only on one + * insert or update query -- insert, update work only on one * relation, so multiple occurence of same resdomno is bogus */ rd = pstate->p_target_relation; @@ -461,7 +461,7 @@ make_targetlist_expr(ParseState *pstate, att->relname = pstrdup(RelationGetRelationName(rd)->data); att->attrs = lcons(makeString(colname), NIL); - target_expr = (Expr *) handleNestedDots(pstate, att, + target_expr = (Expr *) ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno, EXPR_COLUMN_FIRST); while (ar != NIL) @@ -641,9 +641,8 @@ figureColname(Node *expr, Node *resval) { switch (nodeTag(expr)) { - case T_Aggreg: - return (char *) /* XXX */ - ((Aggreg *) expr)->aggname; + case T_Aggreg: + return (char *) ((Aggreg *) expr)->aggname; case T_Expr: if (((Expr *) expr)->opType == FUNC_EXPR) { diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index c67371d308..2a37ad0fe7 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.9 1998/01/07 21:06:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.10 1998/01/20 05:04:32 momjian Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -53,9 +53,9 @@ op_class(Oid opno, int32 opclass, Oid amopid) ObjectIdGetDatum(opno), ObjectIdGetDatum(amopid), 0)) - return (true); + return true; else - return (false); + return false; } /* ---------- ATTRIBUTE CACHES ---------- */ @@ -71,20 +71,15 @@ char * get_attname(Oid relid, AttrNumber attnum) { FormData_pg_attribute att_tup; - char *retval; if (SearchSysCacheStruct(ATTNUM, (char *) &att_tup, ObjectIdGetDatum(relid), UInt16GetDatum(attnum), 0, 0)) - { - retval = pstrdup(att_tup.attname.data); - - return (retval); - } + return pstrdup(att_tup.attname.data); else - return (NULL); + return NULL; } /* @@ -103,9 +98,9 @@ get_attnum(Oid relid, char *attname) ObjectIdGetDatum(relid), PointerGetDatum(attname), 0, 0)) - return (att_tup.attnum); + return att_tup.attnum; else - return (InvalidAttrNumber); + return InvalidAttrNumber; } /* @@ -125,9 +120,9 @@ get_atttype(Oid relid, AttrNumber attnum) ObjectIdGetDatum(relid), UInt16GetDatum(attnum), 0, 0)) - return (att_tup->atttypid); + return att_tup->atttypid; else - return ((Oid) NULL); + return (Oid) NULL; } /* This routine uses the attname instead of the attnum because it @@ -151,14 +146,36 @@ get_attisset(Oid relid, char *attname) elog(ERROR, "get_attisset: no attribute %s in relation %d", attname, relid); if (heap_attisnull(htup, attno)) - return (false); + return false; else { att_tup = (AttributeTupleForm) GETSTRUCT(htup); - return (att_tup->attisset); + return att_tup->attisset; } } +/* + * get_atttypmod - + * + * Given the relation id and the attribute number, + * return the "atttypmod" field from the attribute relation. + * + */ +int +get_atttypmod(Oid relid, AttrNumber attnum) +{ + FormData_pg_attribute att_tup; + + if (SearchSysCacheStruct(ATTNUM, + (char *) &att_tup, + ObjectIdGetDatum(relid), + UInt16GetDatum(attnum), + 0, 0)) + return att_tup.atttypmod; + else + return NULL; +} + /* ---------- INDEX CACHE ---------- */ /* watch this space... @@ -181,9 +198,9 @@ get_opcode(Oid opno) if (SearchSysCacheStruct(OPROID, (char *) &optup, ObjectIdGetDatum(opno), 0, 0, 0)) - return (optup.oprcode); + return optup.oprcode; else - return ((RegProcedure) NULL); + return (RegProcedure) NULL; } /* @@ -200,7 +217,7 @@ get_opname(Oid opno) if (SearchSysCacheStruct(OPROID, (char *) &optup, ObjectIdGetDatum(opno), 0, 0, 0)) - return (pstrdup(optup.oprname.data)); + return pstrdup(optup.oprname.data); else { elog(ERROR, "can't look up operator %d\n", opno); @@ -257,9 +274,9 @@ op_hashjoinable(Oid opno, Oid ltype, Oid rtype) optup.oprcanhash && optup.oprleft == ltype && optup.oprright == rtype) - return (opno); + return opno; else - return (InvalidOid); + return InvalidOid; } /* @@ -276,9 +293,9 @@ get_commutator(Oid opno) if (SearchSysCacheStruct(OPROID, (char *) &optup, ObjectIdGetDatum(opno), 0, 0, 0)) - return (optup.oprcom); + return optup.oprcom; else - return ((Oid) NULL); + return (Oid) NULL; } HeapTuple @@ -289,9 +306,9 @@ get_operator_tuple(Oid opno) if ((optup = SearchSysCacheTuple(OPROID, ObjectIdGetDatum(opno), 0, 0, 0))) - return (optup); + return optup; else - return ((HeapTuple) NULL); + return (HeapTuple) NULL; } /* @@ -308,9 +325,9 @@ get_negator(Oid opno) if (SearchSysCacheStruct(OPROID, (char *) &optup, ObjectIdGetDatum(opno), 0, 0, 0)) - return (optup.oprnegate); + return optup.oprnegate; else - return ((Oid) NULL); + return (Oid) NULL; } /* @@ -327,9 +344,9 @@ get_oprrest(Oid opno) if (SearchSysCacheStruct(OPROID, (char *) &optup, ObjectIdGetDatum(opno), 0, 0, 0)) - return (optup.oprrest); + return optup.oprrest; else - return ((RegProcedure) NULL); + return (RegProcedure) NULL; } /* @@ -346,9 +363,9 @@ get_oprjoin(Oid opno) if (SearchSysCacheStruct(OPROID, (char *) &optup, ObjectIdGetDatum(opno), 0, 0, 0)) - return (optup.oprjoin); + return optup.oprjoin; else - return ((RegProcedure) NULL); + return (RegProcedure) NULL; } /* ---------- RELATION CACHE ---------- */ @@ -367,9 +384,9 @@ get_relnatts(Oid relid) if (SearchSysCacheStruct(RELOID, (char *) &reltup, ObjectIdGetDatum(relid), 0, 0, 0)) - return (reltup.relnatts); + return reltup.relnatts; else - return (InvalidAttrNumber); + return InvalidAttrNumber; } /* @@ -387,11 +404,9 @@ get_rel_name(Oid relid) (char *) &reltup, ObjectIdGetDatum(relid), 0, 0, 0))) - { - return (pstrdup(reltup.relname.data)); - } + return pstrdup(reltup.relname.data); else - return (NULL); + return NULL; } /* ---------- TYPE CACHE ---------- */ @@ -410,9 +425,9 @@ get_typlen(Oid typid) if (SearchSysCacheStruct(TYPOID, (char *) &typtup, ObjectIdGetDatum(typid), 0, 0, 0)) - return (typtup.typlen); + return typtup.typlen; else - return ((int16) NULL); + return (int16) NULL; } /* @@ -430,9 +445,9 @@ get_typbyval(Oid typid) if (SearchSysCacheStruct(TYPOID, (char *) &typtup, ObjectIdGetDatum(typid), 0, 0, 0)) - return ((bool) typtup.typbyval); + return (bool) typtup.typbyval; else - return (false); + return false; } /* @@ -451,9 +466,9 @@ get_typalign(Oid typid) if (SearchSysCacheStruct(TYPOID, (char *) &typtup, ObjectIdGetDatum(typid), 0, 0, 0)) - return (typtup.typalign); + return typtup.typalign; else - return ('i'); + return 'i'; } #endif @@ -470,7 +485,7 @@ get_typdefault(Oid typid) struct varlena *typdefault = (struct varlena *) TypeDefaultRetrieve(typid); - return (typdefault); + return typdefault; } /* @@ -490,13 +505,9 @@ get_typtype(Oid typid) if (SearchSysCacheStruct(TYPOID, (char *) &typtup, ObjectIdGetDatum(typid), 0, 0, 0)) - { - return (typtup.typtype); - } + return typtup.typtype; else - { - return ('\0'); - } + return '\0'; } #endif diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h index 8d1e0fb31f..1381f14f8c 100644 --- a/src/include/parser/parse_agg.h +++ b/src/include/parser/parse_agg.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_agg.h,v 1.4 1998/01/04 04:31:39 momjian Exp $ + * $Id: parse_agg.h,v 1.5 1998/01/20 05:04:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -19,7 +19,6 @@ #include extern void AddAggToParseState(ParseState *pstate, Aggreg *aggreg); -extern void finalizeAggregates(ParseState *pstate, Query *qry); extern void parseCheckAggregates(ParseState *pstate, Query *qry); extern Aggreg *ParseAgg(ParseState *pstate, char *aggname, Oid basetype, List *target, int precedence); diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index 42cbe9c461..b328cc5e5c 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_expr.h,v 1.5 1998/01/16 23:21:01 momjian Exp $ + * $Id: parse_expr.h,v 1.6 1998/01/20 05:04:47 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -21,8 +21,6 @@ extern Node *transformExpr(ParseState *pstate, Node *expr, int precedence); extern Node *transformIdent(ParseState *pstate, Node *expr, int precedence); extern Oid exprType(Node *expr); -extern Node *handleNestedDots(ParseState *pstate, Attr *attr, - int *curr_resno, int precedence); extern Node *parser_typecast2(Node *expr, Oid exprType, Type tp, int attypmod); #endif /* PARSE_EXPR_H */ diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index 12d6ba16b8..0a360df86a 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_func.h,v 1.4 1998/01/04 04:31:42 momjian Exp $ + * $Id: parse_func.h,v 1.5 1998/01/20 05:04:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -42,7 +42,9 @@ typedef struct _CandidateList struct _CandidateList *next; } *CandidateList; -extern Node *ParseFunc(ParseState *pstate, char *funcname, List *fargs, +extern Node *ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, + int *curr_resno, int precedence); +extern Node *ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, int *curr_resno, int precedence); extern void func_error(char *caller, char *funcname, int nargs, Oid *argtypes); diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index e379b92932..eab72589ff 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_relation.h,v 1.4 1998/01/04 04:31:43 momjian Exp $ + * $Id: parse_relation.h,v 1.5 1998/01/20 05:04:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -32,7 +32,6 @@ extern List *expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno); extern int attnameAttNum(Relation rd, char *a); extern bool attnameIsSet(Relation rd, char *name); -extern char *attnumAttName(Relation rd, int attrno); extern int attnumAttNelems(Relation rd, int attid); extern Oid attnumTypeId(Relation rd, int attid); extern void handleTargetColname(ParseState *pstate, char **resname, diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 6110738232..aa30c755bd 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.18 1998/01/19 05:48:55 momjian Exp $ + * $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.19 1998/01/20 05:05:02 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -315,7 +315,7 @@ again: slock_t _res; \ do \ { \ - __asm__("xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(0x1)); \ + __asm__("lock; xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(0x1)); \ } while (_res != 0); \ } while (0) #endif diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index ca07a4a25c..205e9cf437 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: lsyscache.h,v 1.6 1997/09/08 21:55:11 momjian Exp $ + * $Id: lsyscache.h,v 1.7 1998/01/20 05:05:08 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ extern char *get_attname(Oid relid, AttrNumber attnum); extern AttrNumber get_attnum(Oid relid, char *attname); extern Oid get_atttype(Oid relid, AttrNumber attnum); extern bool get_attisset(Oid relid, char *attname); +extern int get_atttypmod(Oid relid, AttrNumber attnum); extern RegProcedure get_opcode(Oid opid); extern char *get_opname(Oid opid); extern bool