diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/analyze.c | 699 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 4 | ||||
-rw-r--r-- | src/backend/parser/parse_agg.c | 64 | ||||
-rw-r--r-- | src/backend/parser/parse_clause.c | 308 | ||||
-rw-r--r-- | src/backend/parser/parse_coerce.c | 93 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 113 | ||||
-rw-r--r-- | src/backend/parser/parse_func.c | 208 | ||||
-rw-r--r-- | src/backend/parser/parse_node.c | 53 | ||||
-rw-r--r-- | src/backend/parser/parse_oper.c | 69 | ||||
-rw-r--r-- | src/backend/parser/parse_relation.c | 103 | ||||
-rw-r--r-- | src/backend/parser/parse_target.c | 93 | ||||
-rw-r--r-- | src/backend/parser/parser.c | 3 | ||||
-rw-r--r-- | src/backend/parser/scansup.c | 4 |
13 files changed, 954 insertions, 860 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index a874c24f5e1..7658443a378 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.141 2000/03/24 23:34:19 tgl Exp $ + * $Id: analyze.c,v 1.142 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,7 @@ #include "utils/builtins.h" #include "utils/numeric.h" -void CheckSelectForUpdate(Query *qry); /* no points for style... */ +void CheckSelectForUpdate(Query *qry); /* no points for style... */ static Query *transformStmt(ParseState *pstate, Node *stmt); static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); @@ -48,8 +48,8 @@ static void transformConstraintAttrs(List *constraintList); static void transformColumnType(ParseState *pstate, ColumnDef *column); /* kluge to return extra info from transformCreateStmt() */ -static List *extras_before; -static List *extras_after; +static List *extras_before; +static List *extras_after; /* @@ -81,7 +81,7 @@ parse_analyze(List *pl, ParseState *parentParseState) while (extras_before != NIL) { result = lappend(result, - transformStmt(pstate, lfirst(extras_before))); + transformStmt(pstate, lfirst(extras_before))); if (pstate->p_target_relation != NULL) heap_close(pstate->p_target_relation, AccessShareLock); pstate->p_target_relation = NULL; @@ -147,13 +147,15 @@ transformStmt(ParseState *pstate, Node *parseTree) n->query = (Query *) transformStmt(pstate, (Node *) n->query); - /* If a list of column names was given, run through and insert these - * into the actual query tree. - thomas 2000-03-08 + /* + * If a list of column names was given, run through and + * insert these into the actual query tree. - thomas + * 2000-03-08 */ if (n->aliases != NIL) { - int i; - List *targetList = n->query->targetList; + int i; + List *targetList = n->query->targetList; if (length(targetList) < length(n->aliases)) elog(ERROR, "CREATE VIEW specifies %d columns" @@ -162,9 +164,10 @@ transformStmt(ParseState *pstate, Node *parseTree) for (i = 0; i < length(n->aliases); i++) { - Ident *id; + Ident *id; TargetEntry *te; - Resdom *rd; + Resdom *rd; + id = nth(i, n->aliases); Assert(nodeTag(id) == T_Ident); te = nth(i, targetList); @@ -210,9 +213,7 @@ transformStmt(ParseState *pstate, Node *parseTree) break; case T_AlterTableStmt: - { - result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); - } + result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); break; /*------------------------ @@ -311,7 +312,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * It is important that we finish processing all the SELECT subclauses * before we start doing any INSERT-specific processing; otherwise * the behavior of SELECT within INSERT might be different from a - * stand-alone SELECT. (Indeed, Postgres up through 6.5 had bugs of + * stand-alone SELECT. (Indeed, Postgres up through 6.5 had bugs of * just that nature...) *---------- */ @@ -323,7 +324,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) qry->qual = transformWhereClause(pstate, stmt->whereClause); - /* Initial processing of HAVING clause is just like WHERE clause. + /* + * Initial processing of HAVING clause is just like WHERE clause. * Additional work will be done in optimizer/plan/planner.c. */ qry->havingQual = transformWhereClause(pstate, stmt->havingClause); @@ -338,7 +340,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) qry->distinctClause = transformDistinctClause(pstate, stmt->distinctClause, qry->targetList, - & qry->sortClause); + &qry->sortClause); qry->hasSubLinks = pstate->p_hasSubLinks; qry->hasAggs = pstate->p_hasAggs; @@ -390,9 +392,11 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) if (resnode->resjunk) { - /* Resjunk nodes need no additional processing, but be sure they - * have names and resnos that do not match any target columns; - * else rewriter or planner might get confused. + + /* + * Resjunk nodes need no additional processing, but be sure + * they have names and resnos that do not match any target + * columns; else rewriter or planner might get confused. */ resnode->resname = "?resjunk?"; resnode->resno = (AttrNumber) pstate->p_last_resno++; @@ -411,9 +415,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) /* * It is possible that the targetlist has fewer entries than were in * the columns list. We do not consider this an error (perhaps we - * should, if the columns list was explictly given?). We must truncate - * the attrnos list to only include the attrs actually provided, - * else we will fail to apply defaults for them below. + * should, if the columns list was explictly given?). We must + * truncate the attrnos list to only include the attrs actually + * provided, else we will fail to apply defaults for them below. */ if (icolumns != NIL) attrnos = ltruncate(numuseratts, attrnos); @@ -422,8 +426,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * Add targetlist items to assign DEFAULT values to any columns that * have defaults and were not assigned to by the user. * - * XXX wouldn't it make more sense to do this further downstream, - * after the rule rewriter? + * XXX wouldn't it make more sense to do this further downstream, after + * the rule rewriter? */ rd_att = pstate->p_target_relation->rd_att; if (rd_att->constr && rd_att->constr->num_defval > 0) @@ -434,24 +438,26 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) while (--ndef >= 0) { - AttrNumber attrno = defval[ndef].adnum; + AttrNumber attrno = defval[ndef].adnum; Form_pg_attribute thisatt = att[attrno - 1]; - TargetEntry *te; + TargetEntry *te; if (intMember((int) attrno, attrnos)) continue; /* there was a user-specified value */ + /* - * No user-supplied value, so add a targetentry with DEFAULT expr - * and correct data for the target column. + * No user-supplied value, so add a targetentry with DEFAULT + * expr and correct data for the target column. */ te = makeTargetEntry( - makeResdom(attrno, - thisatt->atttypid, - thisatt->atttypmod, - pstrdup(NameStr(thisatt->attname)), - 0, 0, false), - stringToNode(defval[ndef].adbin)); + makeResdom(attrno, + thisatt->atttypid, + thisatt->atttypmod, + pstrdup(NameStr(thisatt->attname)), + 0, 0, false), + stringToNode(defval[ndef].adbin)); qry->targetList = lappend(qry->targetList, te); + /* * Make sure the value is coerced to the target column type * (might not be right type if it's not a constant!) @@ -476,7 +482,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * Create a name for an implicitly created index, sequence, constraint, etc. * * The parameters are: the original table name, the original field name, and - * a "type" string (such as "seq" or "pkey"). The field name and/or type + * a "type" string (such as "seq" or "pkey"). The field name and/or type * can be NULL if not relevant. * * The result is a palloc'd string. @@ -484,12 +490,12 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * The basic result we want is "name1_name2_type", omitting "_name2" or * "_type" when those parameters are NULL. However, we must generate * a name with less than NAMEDATALEN characters! So, we truncate one or - * both names if necessary to make a short-enough string. The type part + * both names if necessary to make a short-enough string. The type part * is never truncated (so it had better be reasonably short). * * To reduce the probability of collisions, we might someday add more * smarts to this routine, like including some "hash" characters computed - * from the truncated characters. Currently it seems best to keep it simple, + * from the truncated characters. Currently it seems best to keep it simple, * so that the generated names are easily predictable by a person. */ static char * @@ -513,10 +519,11 @@ makeObjectName(char *name1, char *name2, char *typename) if (typename) overhead += strlen(typename) + 1; - availchars = NAMEDATALEN-1 - overhead; + availchars = NAMEDATALEN - 1 - overhead; - /* If we must truncate, preferentially truncate the longer name. - * This logic could be expressed without a loop, but it's simple and + /* + * If we must truncate, preferentially truncate the longer name. This + * logic could be expressed without a loop, but it's simple and * obvious as a loop. */ while (name1chars + name2chars > availchars) @@ -534,13 +541,13 @@ makeObjectName(char *name1, char *name2, char *typename) if (name2) { name[ndx++] = '_'; - strncpy(name+ndx, name2, name2chars); + strncpy(name + ndx, name2, name2chars); ndx += name2chars; } if (typename) { name[ndx++] = '_'; - strcpy(name+ndx, typename); + strcpy(name + ndx, typename); } else name[ndx] = '\0'; @@ -556,7 +563,8 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices) List *ilist; char typename[NAMEDATALEN]; - /* The type name for makeObjectName is label, or labelN if that's + /* + * The type name for makeObjectName is label, or labelN if that's * necessary to prevent collisions among multiple indexes for the same * table. Note there is no check for collisions with already-existing * indexes; this ought to be rethought someday. @@ -570,6 +578,7 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices) foreach(ilist, indices) { IndexStmt *index = lfirst(ilist); + if (strcmp(iname, index->idxname) == 0) break; } @@ -597,28 +606,28 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices) static Query * transformCreateStmt(ParseState *pstate, CreateStmt *stmt) { - Query *q; - List *elements; - Node *element; - List *columns; - List *dlist; - ColumnDef *column; - List *constraints, - *clist; - Constraint *constraint; - List *fkconstraints, /* List of FOREIGN KEY constraints to */ - *fkclist; /* add finally */ - FkConstraint *fkconstraint; - List *keys; - Ident *key; - List *blist = NIL; /* "before list" of things to do before - * creating the table */ - List *ilist = NIL; /* "index list" of things to do after - * creating the table */ - IndexStmt *index, - *pkey = NULL; - IndexElem *iparam; - bool saw_nullable; + Query *q; + List *elements; + Node *element; + List *columns; + List *dlist; + ColumnDef *column; + List *constraints, + *clist; + Constraint *constraint; + List *fkconstraints, /* List of FOREIGN KEY constraints to */ + *fkclist; /* add finally */ + FkConstraint *fkconstraint; + List *keys; + Ident *key; + List *blist = NIL; /* "before list" of things to do before + * creating the table */ + List *ilist = NIL; /* "index list" of things to do after + * creating the table */ + IndexStmt *index, + *pkey = NULL; + IndexElem *iparam; + bool saw_nullable; q = makeNode(Query); q->commandType = CMD_UTILITY; @@ -647,18 +656,19 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) { char *sname; char *qstring; - A_Const *snamenode; + A_Const *snamenode; FuncCall *funccallnode; CreateSeqStmt *sequence; /* - * Create appropriate constraints for SERIAL. We do this - * in full, rather than shortcutting, so that we will - * detect any conflicting constraints the user wrote - * (like a different DEFAULT). + * Create appropriate constraints for SERIAL. We do + * this in full, rather than shortcutting, so that we + * will detect any conflicting constraints the user + * wrote (like a different DEFAULT). */ sname = makeObjectName(stmt->relname, column->colname, "seq"); + /* * Create an expression tree representing the function * call nextval('"sequencename"') @@ -701,7 +711,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) sequence->options = NIL; elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'", - sequence->seqname, stmt->relname, column->colname); + sequence->seqname, stmt->relname, column->colname); blist = lcons(sequence, NIL); } @@ -724,12 +734,13 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) */ if (IsA(constraint, FkConstraint)) { - Ident *id = makeNode(Ident); - id->name = column->colname; - id->indirection = NIL; - id->isRel = false; + Ident *id = makeNode(Ident); + + id->name = column->colname; + id->indirection = NIL; + id->isRel = false; - fkconstraint = (FkConstraint *)constraint; + fkconstraint = (FkConstraint *) constraint; fkconstraint->fk_attrs = lappend(NIL, id); fkconstraints = lappend(fkconstraints, constraint); @@ -747,7 +758,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) break; case CONSTR_NOTNULL: - if (saw_nullable && ! column->is_not_null) + if (saw_nullable && !column->is_not_null) elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration" " for '%s.%s'", stmt->relname, column->colname); column->is_not_null = TRUE; @@ -910,7 +921,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) if (strcmp(column->colname, key->name) == 0) break; } - if (columns == NIL) /* fell off end of list? */ + if (columns == NIL) /* fell off end of list? */ elog(ERROR, "CREATE TABLE: column '%s' named in key does not exist", key->name); @@ -927,7 +938,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist); } - if (index->idxname == NULL) /* should not happen */ + if (index->idxname == NULL) /* should not happen */ elog(ERROR, "CREATE TABLE: failed to make implicit index name"); ilist = lappend(ilist, index); @@ -945,9 +956,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) ilist = NIL; while (dlist != NIL) { - List *pcols, *icols; - int plen, ilen; - int keep = TRUE; + List *pcols, + *icols; + int plen, + ilen; + int keep = TRUE; index = lfirst(dlist); pcols = pkey->indexParams; @@ -962,10 +975,10 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) keep = FALSE; while ((pcols != NIL) && (icols != NIL)) { - IndexElem *pcol = lfirst(pcols); - IndexElem *icol = lfirst(icols); - char *pname = pcol->name; - char *iname = icol->name; + IndexElem *pcol = lfirst(pcols); + IndexElem *icol = lfirst(icols); + char *pname = pcol->name; + char *iname = icol->name; /* different names? then no match... */ if (strcmp(iname, pname) != 0) @@ -999,22 +1012,22 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) extras_after = ilist; /* - * Now process the FOREIGN KEY constraints and add appropriate - * queries to the extras_after statements list. + * Now process the FOREIGN KEY constraints and add appropriate queries + * to the extras_after statements list. * */ if (fkconstraints != NIL) { - CreateTrigStmt *fk_trigger; - List *fk_attr; - List *pk_attr; - Ident *id; + CreateTrigStmt *fk_trigger; + List *fk_attr; + List *pk_attr; + Ident *id; elog(NOTICE, "CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)"); - foreach (fkclist, fkconstraints) + foreach(fkclist, fkconstraints) { - fkconstraint = (FkConstraint *)lfirst(fkclist); + fkconstraint = (FkConstraint *) lfirst(fkclist); /* * If the constraint has no name, set it to <unnamed> @@ -1024,37 +1037,37 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) fkconstraint->constr_name = "<unnamed>"; /* - * If the attribute list for the referenced table was - * omitted, lookup for the definition of the primary key. - * If the referenced table is this table, use the definition - * we found above, rather than looking to the system - * tables. + * If the attribute list for the referenced table was omitted, + * lookup for the definition of the primary key. If the + * referenced table is this table, use the definition we found + * above, rather than looking to the system tables. * */ if (fkconstraint->fk_attrs != NIL && fkconstraint->pk_attrs == NIL) { if (strcmp(fkconstraint->pktable_name, stmt->relname) != 0) transformFkeyGetPrimaryKey(fkconstraint); - else if (pkey != NULL) + else if (pkey != NULL) { - List *pkey_attr = pkey->indexParams; - List *attr; - IndexElem *ielem; - Ident *pkattr; + List *pkey_attr = pkey->indexParams; + List *attr; + IndexElem *ielem; + Ident *pkattr; - foreach (attr, pkey_attr) + foreach(attr, pkey_attr) { ielem = lfirst(attr); - pkattr = (Ident *)makeNode(Ident); + pkattr = (Ident *) makeNode(Ident); pkattr->name = pstrdup(ielem->name); pkattr->indirection = NIL; pkattr->isRel = false; fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr); - } + } } - else { + else + { elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found", - fkconstraint->pktable_name); + fkconstraint->pktable_name); } } @@ -1063,85 +1076,87 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) * action. * */ - fk_trigger = (CreateTrigStmt *)makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relname = stmt->relname; - fk_trigger->funcname = "RI_FKey_check_ins"; - fk_trigger->before = false; - fk_trigger->row = true; - fk_trigger->actions[0] = 'i'; - fk_trigger->actions[1] = 'u'; - fk_trigger->actions[2] = '\0'; - fk_trigger->lang = NULL; - fk_trigger->text = NULL; - fk_trigger->attr = NIL; - fk_trigger->when = NULL; - fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; - fk_trigger->constrrelname = fkconstraint->pktable_name; - - fk_trigger->args = NIL; + fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt); + fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->relname = stmt->relname; + fk_trigger->funcname = "RI_FKey_check_ins"; + fk_trigger->before = false; + fk_trigger->row = true; + fk_trigger->actions[0] = 'i'; + fk_trigger->actions[1] = 'u'; + fk_trigger->actions[2] = '\0'; + fk_trigger->lang = NULL; + fk_trigger->text = NULL; + + fk_trigger->attr = NIL; + fk_trigger->when = NULL; + fk_trigger->isconstraint = true; + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; + fk_trigger->constrrelname = fkconstraint->pktable_name; + + fk_trigger->args = NIL; fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->constr_name); + fkconstraint->constr_name); fk_trigger->args = lappend(fk_trigger->args, - stmt->relname); + stmt->relname); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->pktable_name); + fkconstraint->pktable_name); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->match_type); + fkconstraint->match_type); fk_attr = fkconstraint->fk_attrs; pk_attr = fkconstraint->pk_attrs; if (length(fk_attr) != length(pk_attr)) { elog(NOTICE, "Illegal FOREIGN KEY definition REFERENCES \"%s\"", - fkconstraint->pktable_name); + fkconstraint->pktable_name); elog(ERROR, "number of key attributes in referenced table must be equal to foreign key"); } while (fk_attr != NIL) { - id = (Ident *)lfirst(fk_attr); + id = (Ident *) lfirst(fk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); - id = (Ident *)lfirst(pk_attr); + id = (Ident *) lfirst(pk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); fk_attr = lnext(fk_attr); pk_attr = lnext(pk_attr); } - extras_after = lappend(extras_after, (Node *)fk_trigger); + extras_after = lappend(extras_after, (Node *) fk_trigger); /* - * Build a CREATE CONSTRAINT TRIGGER statement for the - * ON DELETE action fired on the PK table !!! + * Build a CREATE CONSTRAINT TRIGGER statement for the ON + * DELETE action fired on the PK table !!! * */ - fk_trigger = (CreateTrigStmt *)makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relname = fkconstraint->pktable_name; - fk_trigger->before = false; - fk_trigger->row = true; - fk_trigger->actions[0] = 'd'; - fk_trigger->actions[1] = '\0'; - fk_trigger->lang = NULL; - fk_trigger->text = NULL; - fk_trigger->attr = NIL; - fk_trigger->when = NULL; - fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; - fk_trigger->constrrelname = stmt->relname; + fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt); + fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->relname = fkconstraint->pktable_name; + fk_trigger->before = false; + fk_trigger->row = true; + fk_trigger->actions[0] = 'd'; + fk_trigger->actions[1] = '\0'; + fk_trigger->lang = NULL; + fk_trigger->text = NULL; + + fk_trigger->attr = NIL; + fk_trigger->when = NULL; + fk_trigger->isconstraint = true; + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; + fk_trigger->constrrelname = stmt->relname; switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK) - >> FKCONSTR_ON_DELETE_SHIFT) + >> FKCONSTR_ON_DELETE_SHIFT) { case FKCONSTR_ON_KEY_NOACTION: fk_trigger->funcname = "RI_FKey_noaction_del"; break; case FKCONSTR_ON_KEY_RESTRICT: - fk_trigger->deferrable = false; - fk_trigger->initdeferred = false; - fk_trigger->funcname = "RI_FKey_restrict_del"; + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; + fk_trigger->funcname = "RI_FKey_restrict_del"; break; case FKCONSTR_ON_KEY_CASCADE: fk_trigger->funcname = "RI_FKey_cascade_del"; @@ -1157,61 +1172,62 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) break; } - fk_trigger->args = NIL; + fk_trigger->args = NIL; fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->constr_name); + fkconstraint->constr_name); fk_trigger->args = lappend(fk_trigger->args, - stmt->relname); + stmt->relname); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->pktable_name); + fkconstraint->pktable_name); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->match_type); + fkconstraint->match_type); fk_attr = fkconstraint->fk_attrs; pk_attr = fkconstraint->pk_attrs; while (fk_attr != NIL) { - id = (Ident *)lfirst(fk_attr); + id = (Ident *) lfirst(fk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); - id = (Ident *)lfirst(pk_attr); + id = (Ident *) lfirst(pk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); fk_attr = lnext(fk_attr); pk_attr = lnext(pk_attr); } - extras_after = lappend(extras_after, (Node *)fk_trigger); + extras_after = lappend(extras_after, (Node *) fk_trigger); /* - * Build a CREATE CONSTRAINT TRIGGER statement for the - * ON UPDATE action fired on the PK table !!! + * Build a CREATE CONSTRAINT TRIGGER statement for the ON + * UPDATE action fired on the PK table !!! * */ - fk_trigger = (CreateTrigStmt *)makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relname = fkconstraint->pktable_name; - fk_trigger->before = false; - fk_trigger->row = true; - fk_trigger->actions[0] = 'u'; - fk_trigger->actions[1] = '\0'; - fk_trigger->lang = NULL; - fk_trigger->text = NULL; - fk_trigger->attr = NIL; - fk_trigger->when = NULL; - fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; - fk_trigger->constrrelname = stmt->relname; + fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt); + fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->relname = fkconstraint->pktable_name; + fk_trigger->before = false; + fk_trigger->row = true; + fk_trigger->actions[0] = 'u'; + fk_trigger->actions[1] = '\0'; + fk_trigger->lang = NULL; + fk_trigger->text = NULL; + + fk_trigger->attr = NIL; + fk_trigger->when = NULL; + fk_trigger->isconstraint = true; + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; + fk_trigger->constrrelname = stmt->relname; switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK) - >> FKCONSTR_ON_UPDATE_SHIFT) + >> FKCONSTR_ON_UPDATE_SHIFT) { case FKCONSTR_ON_KEY_NOACTION: fk_trigger->funcname = "RI_FKey_noaction_upd"; break; case FKCONSTR_ON_KEY_RESTRICT: - fk_trigger->deferrable = false; - fk_trigger->initdeferred = false; - fk_trigger->funcname = "RI_FKey_restrict_upd"; + fk_trigger->deferrable = false; + fk_trigger->initdeferred = false; + fk_trigger->funcname = "RI_FKey_restrict_upd"; break; case FKCONSTR_ON_KEY_CASCADE: fk_trigger->funcname = "RI_FKey_cascade_upd"; @@ -1227,30 +1243,30 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt) break; } - fk_trigger->args = NIL; + fk_trigger->args = NIL; fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->constr_name); + fkconstraint->constr_name); fk_trigger->args = lappend(fk_trigger->args, - stmt->relname); + stmt->relname); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->pktable_name); + fkconstraint->pktable_name); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->match_type); + fkconstraint->match_type); fk_attr = fkconstraint->fk_attrs; pk_attr = fkconstraint->pk_attrs; while (fk_attr != NIL) { - id = (Ident *)lfirst(fk_attr); + id = (Ident *) lfirst(fk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); - id = (Ident *)lfirst(pk_attr); + id = (Ident *) lfirst(pk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); fk_attr = lnext(fk_attr); pk_attr = lnext(pk_attr); } - extras_after = lappend(extras_after, (Node *)fk_trigger); + extras_after = lappend(extras_after, (Node *) fk_trigger); } } @@ -1408,7 +1424,8 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) qry->qual = transformWhereClause(pstate, stmt->whereClause); - /* Initial processing of HAVING clause is just like WHERE clause. + /* + * Initial processing of HAVING clause is just like WHERE clause. * Additional work will be done in optimizer/plan/planner.c. */ qry->havingQual = transformWhereClause(pstate, stmt->havingClause); @@ -1424,7 +1441,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) qry->distinctClause = transformDistinctClause(pstate, stmt->distinctClause, qry->targetList, - & qry->sortClause); + &qry->sortClause); qry->hasSubLinks = pstate->p_hasSubLinks; qry->hasAggs = pstate->p_hasAggs; @@ -1506,9 +1523,11 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) if (resnode->resjunk) { - /* Resjunk nodes need no additional processing, but be sure they - * have names and resnos that do not match any target columns; - * else rewriter or planner might get confused. + + /* + * Resjunk nodes need no additional processing, but be sure + * they have names and resnos that do not match any target + * columns; else rewriter or planner might get confused. */ resnode->resname = "?resjunk?"; resnode->resno = (AttrNumber) pstate->p_last_resno++; @@ -1551,38 +1570,42 @@ transformCursorStmt(ParseState *pstate, SelectStmt *stmt) /* * tranformAlterTableStmt - - * transform an Alter Table Statement + * transform an Alter Table Statement * */ static Query * -transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) +transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) { - Query *qry; + Query *qry; + qry = makeNode(Query); qry->commandType = CMD_UTILITY; - /* - * The only subtypes that currently have special handling are - * 'A'dd column and Add 'C'onstraint. In addition, right now - * only Foreign Key 'C'onstraints have a special transformation. + /* + * The only subtypes that currently have special handling are 'A'dd + * column and Add 'C'onstraint. In addition, right now only Foreign + * Key 'C'onstraints have a special transformation. * */ - switch (stmt->subtype) { + switch (stmt->subtype) + { case 'A': transformColumnType(pstate, (ColumnDef *) stmt->def); break; - case 'C': - if (stmt->def && nodeTag(stmt->def) == T_FkConstraint ) + case 'C': + if (stmt->def && nodeTag(stmt->def) == T_FkConstraint) { - CreateTrigStmt *fk_trigger; - List *fk_attr; - List *pk_attr; - Ident *id; - FkConstraint *fkconstraint; + CreateTrigStmt *fk_trigger; + List *fk_attr; + List *pk_attr; + Ident *id; + FkConstraint *fkconstraint; + extras_after = NIL; elog(NOTICE, "ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)"); fkconstraint = (FkConstraint *) stmt->def; + /* * If the constraint has no name, set it to <unnamed> * @@ -1599,69 +1622,70 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) transformFkeyGetPrimaryKey(fkconstraint); /* - * Build a CREATE CONSTRAINT TRIGGER statement for the CHECK - * action. + * Build a CREATE CONSTRAINT TRIGGER statement for the + * CHECK action. * */ - fk_trigger = (CreateTrigStmt *)makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relname = stmt->relname; - fk_trigger->funcname = "RI_FKey_check_ins"; - fk_trigger->before = false; - fk_trigger->row = true; - fk_trigger->actions[0] = 'i'; - fk_trigger->actions[1] = 'u'; - fk_trigger->actions[2] = '\0'; - fk_trigger->lang = NULL; - fk_trigger->text = NULL; - fk_trigger->attr = NIL; - fk_trigger->when = NULL; - fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; - fk_trigger->constrrelname = fkconstraint->pktable_name; - - fk_trigger->args = NIL; + fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt); + fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->relname = stmt->relname; + fk_trigger->funcname = "RI_FKey_check_ins"; + fk_trigger->before = false; + fk_trigger->row = true; + fk_trigger->actions[0] = 'i'; + fk_trigger->actions[1] = 'u'; + fk_trigger->actions[2] = '\0'; + fk_trigger->lang = NULL; + fk_trigger->text = NULL; + + fk_trigger->attr = NIL; + fk_trigger->when = NULL; + fk_trigger->isconstraint = true; + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; + fk_trigger->constrrelname = fkconstraint->pktable_name; + + fk_trigger->args = NIL; fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->constr_name); + fkconstraint->constr_name); fk_trigger->args = lappend(fk_trigger->args, - stmt->relname); + stmt->relname); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->pktable_name); + fkconstraint->pktable_name); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->match_type); + fkconstraint->match_type); fk_attr = fkconstraint->fk_attrs; pk_attr = fkconstraint->pk_attrs; if (length(fk_attr) != length(pk_attr)) { elog(NOTICE, "Illegal FOREIGN KEY definition REFERENCES \"%s\"", - fkconstraint->pktable_name); + fkconstraint->pktable_name); elog(ERROR, "number of key attributes in referenced table must be equal to foreign key"); } while (fk_attr != NIL) { - id = (Ident *)lfirst(fk_attr); + id = (Ident *) lfirst(fk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); - - id = (Ident *)lfirst(pk_attr); + + id = (Ident *) lfirst(pk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); fk_attr = lnext(fk_attr); pk_attr = lnext(pk_attr); } - extras_after = lappend(extras_after, (Node *)fk_trigger); + extras_after = lappend(extras_after, (Node *) fk_trigger); /* - * Build a CREATE CONSTRAINT TRIGGER statement for the - * ON DELETE action fired on the PK table !!! + * Build a CREATE CONSTRAINT TRIGGER statement for the ON + * DELETE action fired on the PK table !!! * */ - fk_trigger = (CreateTrigStmt *)makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relname = fkconstraint->pktable_name; + fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt); + fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->relname = fkconstraint->pktable_name; switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK) - >> FKCONSTR_ON_DELETE_SHIFT) + >> FKCONSTR_ON_DELETE_SHIFT) { case FKCONSTR_ON_KEY_NOACTION: fk_trigger->funcname = "RI_FKey_noaction_del"; @@ -1682,54 +1706,55 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) elog(ERROR, "Only one ON DELETE action can be specified for FOREIGN KEY constraint"); break; } - fk_trigger->before = false; - fk_trigger->row = true; - fk_trigger->actions[0] = 'd'; - fk_trigger->actions[1] = '\0'; - fk_trigger->lang = NULL; - fk_trigger->text = NULL; - fk_trigger->attr = NIL; - fk_trigger->when = NULL; - fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; - fk_trigger->constrrelname = stmt->relname; - - fk_trigger->args = NIL; + fk_trigger->before = false; + fk_trigger->row = true; + fk_trigger->actions[0] = 'd'; + fk_trigger->actions[1] = '\0'; + fk_trigger->lang = NULL; + fk_trigger->text = NULL; + + fk_trigger->attr = NIL; + fk_trigger->when = NULL; + fk_trigger->isconstraint = true; + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; + fk_trigger->constrrelname = stmt->relname; + + fk_trigger->args = NIL; fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->constr_name); + fkconstraint->constr_name); fk_trigger->args = lappend(fk_trigger->args, - stmt->relname); + stmt->relname); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->pktable_name); + fkconstraint->pktable_name); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->match_type); + fkconstraint->match_type); fk_attr = fkconstraint->fk_attrs; pk_attr = fkconstraint->pk_attrs; while (fk_attr != NIL) { - id = (Ident *)lfirst(fk_attr); + id = (Ident *) lfirst(fk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); - id = (Ident *)lfirst(pk_attr); + id = (Ident *) lfirst(pk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); fk_attr = lnext(fk_attr); pk_attr = lnext(pk_attr); } - extras_after = lappend(extras_after, (Node *)fk_trigger); + extras_after = lappend(extras_after, (Node *) fk_trigger); /* - * Build a CREATE CONSTRAINT TRIGGER statement for the - * ON UPDATE action fired on the PK table !!! + * Build a CREATE CONSTRAINT TRIGGER statement for the ON + * UPDATE action fired on the PK table !!! * */ - fk_trigger = (CreateTrigStmt *)makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relname = fkconstraint->pktable_name; + fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt); + fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->relname = fkconstraint->pktable_name; switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK) - >> FKCONSTR_ON_UPDATE_SHIFT) + >> FKCONSTR_ON_UPDATE_SHIFT) { case FKCONSTR_ON_KEY_NOACTION: fk_trigger->funcname = "RI_FKey_noaction_upd"; @@ -1750,43 +1775,44 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) elog(ERROR, "Only one ON UPDATE action can be specified for FOREIGN KEY constraint"); break; } - fk_trigger->before = false; - fk_trigger->row = true; - fk_trigger->actions[0] = 'u'; - fk_trigger->actions[1] = '\0'; - fk_trigger->lang = NULL; - fk_trigger->text = NULL; - fk_trigger->attr = NIL; - fk_trigger->when = NULL; - fk_trigger->isconstraint = true; - fk_trigger->deferrable = fkconstraint->deferrable; - fk_trigger->initdeferred = fkconstraint->initdeferred; - fk_trigger->constrrelname = stmt->relname; - - fk_trigger->args = NIL; + fk_trigger->before = false; + fk_trigger->row = true; + fk_trigger->actions[0] = 'u'; + fk_trigger->actions[1] = '\0'; + fk_trigger->lang = NULL; + fk_trigger->text = NULL; + + fk_trigger->attr = NIL; + fk_trigger->when = NULL; + fk_trigger->isconstraint = true; + fk_trigger->deferrable = fkconstraint->deferrable; + fk_trigger->initdeferred = fkconstraint->initdeferred; + fk_trigger->constrrelname = stmt->relname; + + fk_trigger->args = NIL; fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->constr_name); + fkconstraint->constr_name); fk_trigger->args = lappend(fk_trigger->args, - stmt->relname); + stmt->relname); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->pktable_name); + fkconstraint->pktable_name); fk_trigger->args = lappend(fk_trigger->args, - fkconstraint->match_type); + fkconstraint->match_type); fk_attr = fkconstraint->fk_attrs; pk_attr = fkconstraint->pk_attrs; while (fk_attr != NIL) { - id = (Ident *)lfirst(fk_attr); + id = (Ident *) lfirst(fk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); - id = (Ident *)lfirst(pk_attr); + id = (Ident *) lfirst(pk_attr); fk_trigger->args = lappend(fk_trigger->args, id->name); fk_attr = lnext(fk_attr); pk_attr = lnext(pk_attr); } - extras_after = lappend(extras_after, (Node *)fk_trigger); + extras_after = lappend(extras_after, (Node *) fk_trigger); } break; default: @@ -1975,16 +2001,16 @@ transformForUpdate(Query *qry, List *forUpdate) static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint) { - Relation pkrel; - Form_pg_attribute *pkrel_attrs; - Relation indexRd; - HeapScanDesc indexSd; - ScanKeyData key; - HeapTuple indexTup; - Form_pg_index indexStruct = NULL; - Ident *pkattr; - int pkattno; - int i; + Relation pkrel; + Form_pg_attribute *pkrel_attrs; + Relation indexRd; + HeapScanDesc indexSd; + ScanKeyData key; + HeapTuple indexTup; + Form_pg_index indexStruct = NULL; + Ident *pkattr; + int pkattno; + int i; /* ---------- * Open the referenced table and get the attributes list @@ -1993,7 +2019,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint) pkrel = heap_openr(fkconstraint->pktable_name, AccessShareLock); if (pkrel == NULL) elog(ERROR, "referenced table \"%s\" not found", - fkconstraint->pktable_name); + fkconstraint->pktable_name); pkrel_attrs = pkrel->rd_att->attrs; /* ---------- @@ -2003,13 +2029,13 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint) */ indexRd = heap_openr(IndexRelationName, AccessShareLock); ScanKeyEntryInitialize(&key, 0, Anum_pg_index_indrelid, - F_OIDEQ, - ObjectIdGetDatum(pkrel->rd_id)); - indexSd = heap_beginscan(indexRd, /* scan desc */ - false, /* scan backward flag */ - SnapshotNow, /* NOW snapshot */ - 1, /* number scan keys */ - &key); /* scan keys */ + F_OIDEQ, + ObjectIdGetDatum(pkrel->rd_id)); + indexSd = heap_beginscan(indexRd, /* scan desc */ + false, /* scan backward flag */ + SnapshotNow, /* NOW snapshot */ + 1, /* number scan keys */ + &key); /* scan keys */ /* ---------- * Fetch the index with indisprimary == true @@ -2020,9 +2046,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint) indexStruct = (Form_pg_index) GETSTRUCT(indexTup); if (indexStruct->indisprimary) - { break; - } } /* ---------- @@ -2031,7 +2055,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint) */ if (!HeapTupleIsValid(indexTup)) elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found", - fkconstraint->pktable_name); + fkconstraint->pktable_name); /* ---------- * Now build the list of PK attributes from the indkey definition @@ -2041,7 +2065,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint) for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) { pkattno = indexStruct->indkey[i]; - pkattr = (Ident *)makeNode(Ident); + pkattr = (Ident *) makeNode(Ident); pkattr->name = nameout(&(pkrel_attrs[pkattno - 1]->attname)); pkattr->indirection = NIL; pkattr->isRel = false; @@ -2076,9 +2100,9 @@ transformConstraintAttrs(List *constraintList) foreach(clist, constraintList) { - Node *node = lfirst(clist); + Node *node = lfirst(clist); - if (! IsA(node, Constraint)) + if (!IsA(node, Constraint)) { lastprimarynode = node; /* reset flags for new primary node */ @@ -2087,13 +2111,13 @@ transformConstraintAttrs(List *constraintList) } else { - Constraint *con = (Constraint *) node; + Constraint *con = (Constraint *) node; switch (con->contype) { case CONSTR_ATTR_DEFERRABLE: if (lastprimarynode == NULL || - ! IsA(lastprimarynode, FkConstraint)) + !IsA(lastprimarynode, FkConstraint)) elog(ERROR, "Misplaced DEFERRABLE clause"); if (saw_deferrability) elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"); @@ -2102,7 +2126,7 @@ transformConstraintAttrs(List *constraintList) break; case CONSTR_ATTR_NOT_DEFERRABLE: if (lastprimarynode == NULL || - ! IsA(lastprimarynode, FkConstraint)) + !IsA(lastprimarynode, FkConstraint)) elog(ERROR, "Misplaced NOT DEFERRABLE clause"); if (saw_deferrability) elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"); @@ -2114,21 +2138,25 @@ transformConstraintAttrs(List *constraintList) break; case CONSTR_ATTR_DEFERRED: if (lastprimarynode == NULL || - ! IsA(lastprimarynode, FkConstraint)) + !IsA(lastprimarynode, FkConstraint)) elog(ERROR, "Misplaced INITIALLY DEFERRED clause"); if (saw_initially) elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"); saw_initially = true; ((FkConstraint *) lastprimarynode)->initdeferred = true; - /* If only INITIALLY DEFERRED appears, assume DEFERRABLE */ - if (! saw_deferrability) + + /* + * If only INITIALLY DEFERRED appears, assume + * DEFERRABLE + */ + if (!saw_deferrability) ((FkConstraint *) lastprimarynode)->deferrable = true; - else if (! ((FkConstraint *) lastprimarynode)->deferrable) + else if (!((FkConstraint *) lastprimarynode)->deferrable) elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE"); break; case CONSTR_ATTR_IMMEDIATE: if (lastprimarynode == NULL || - ! IsA(lastprimarynode, FkConstraint)) + !IsA(lastprimarynode, FkConstraint)) elog(ERROR, "Misplaced INITIALLY IMMEDIATE clause"); if (saw_initially) elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"); @@ -2153,9 +2181,10 @@ transformConstraintAttrs(List *constraintList) static void transformColumnType(ParseState *pstate, ColumnDef *column) { + /* - * If the column doesn't have an explicitly specified typmod, - * check to see if we want to insert a default length. + * If the column doesn't have an explicitly specified typmod, check to + * see if we want to insert a default length. * * Note that we deliberately do NOT look at array or set information * here; "numeric[]" needs the same default typmod as "numeric". @@ -2164,13 +2193,13 @@ transformColumnType(ParseState *pstate, ColumnDef *column) { switch (typeTypeId(typenameType(column->typename->name))) { - case BPCHAROID: + case BPCHAROID: /* "char" -> "char(1)" */ column->typename->typmod = VARHDRSZ + 1; break; case NUMERICOID: column->typename->typmod = VARHDRSZ + - ((NUMERIC_DEFAULT_PRECISION<<16) | NUMERIC_DEFAULT_SCALE); + ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE); break; } } diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index cd1b66a7f8e..f30abe49153 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.70 2000/04/07 13:39:34 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.71 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -227,7 +227,7 @@ static ScanKeyword ScanKeywords[] = { {"stdin", STDIN}, {"stdout", STDOUT}, {"substring", SUBSTRING}, - {"sysid", SYSID}, + {"sysid", SYSID}, {"table", TABLE}, {"temp", TEMP}, {"temporary", TEMPORARY}, diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 8a37485bbd6..fff451206bb 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.36 2000/03/17 02:36:17 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.37 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -24,15 +24,16 @@ #include "utils/lsyscache.h" #include "utils/syscache.h" -typedef struct { +typedef struct +{ ParseState *pstate; List *groupClauses; } check_ungrouped_columns_context; static void check_ungrouped_columns(Node *node, ParseState *pstate, - List *groupClauses); + List *groupClauses); static bool check_ungrouped_columns_walker(Node *node, - check_ungrouped_columns_context *context); + check_ungrouped_columns_context *context); /* * check_ungrouped_columns - @@ -46,7 +47,7 @@ static bool check_ungrouped_columns_walker(Node *node, * * NOTE: in the case of a SubLink, expression_tree_walker does not descend * into the subquery. This means we will fail to detect ungrouped columns - * that appear as outer-level variables within a subquery. That case seems + * that appear as outer-level variables within a subquery. That case seems * unreasonably hard to handle here. Instead, we expect the planner to check * for ungrouped columns after it's found all the outer-level references * inside the subquery and converted them into a list of parameters for the @@ -56,7 +57,7 @@ static void check_ungrouped_columns(Node *node, ParseState *pstate, List *groupClauses) { - check_ungrouped_columns_context context; + check_ungrouped_columns_context context; context.pstate = pstate; context.groupClauses = groupClauses; @@ -71,13 +72,16 @@ check_ungrouped_columns_walker(Node *node, if (node == NULL) return false; - if (IsA(node, Const) || IsA(node, Param)) + if (IsA(node, Const) ||IsA(node, Param)) return false; /* constants are always acceptable */ + /* - * If we find an aggregate function, do not recurse into its arguments. + * If we find an aggregate function, do not recurse into its + * arguments. */ if (IsA(node, Aggref)) return false; + /* * Check to see if subexpression as a whole matches any GROUP BY item. * We need to do this at every recursion level so that we recognize @@ -88,17 +92,19 @@ check_ungrouped_columns_walker(Node *node, if (equal(node, lfirst(gl))) return false; /* acceptable, do not descend more */ } + /* * If we have an ungrouped Var, we have a failure --- unless it is an * outer-level Var. In that case it's a constant as far as this query - * level is concerned, and we can accept it. (If it's ungrouped as far - * as the upper query is concerned, that's someone else's problem...) + * level is concerned, and we can accept it. (If it's ungrouped as + * far as the upper query is concerned, that's someone else's + * problem...) */ if (IsA(node, Var)) { - Var *var = (Var *) node; - RangeTblEntry *rte; - char *attname; + Var *var = (Var *) node; + RangeTblEntry *rte; + char *attname; if (var->varlevelsup > 0) return false; /* outer-level Var is acceptable */ @@ -107,7 +113,7 @@ check_ungrouped_columns_walker(Node *node, (int) var->varno <= length(context->pstate->p_rtable)); rte = rt_fetch(var->varno, context->pstate->p_rtable); attname = get_attname(rte->relid, var->varattno); - if (! attname) + if (!attname) elog(ERROR, "cache lookup of attribute %d in relation %u failed", var->varattno, rte->relid); elog(ERROR, "Attribute %s.%s must be GROUPed or used in an aggregate function", @@ -139,9 +145,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry) /* * Aggregates must never appear in WHERE clauses. (Note this check * should appear first to deliver an appropriate error message; - * otherwise we are likely to complain about some innocent variable - * in the target list, which is outright misleading if the problem - * is in WHERE.) + * otherwise we are likely to complain about some innocent variable in + * the target list, which is outright misleading if the problem is in + * WHERE.) */ if (contain_agg_clause(qry->qual)) elog(ERROR, "Aggregates not allowed in WHERE clause"); @@ -149,14 +155,14 @@ parseCheckAggregates(ParseState *pstate, Query *qry) /* * No aggregates allowed in GROUP BY clauses, either. * - * While we are at it, build a list of the acceptable GROUP BY expressions - * for use by check_ungrouped_columns() (this avoids repeated scans of the - * targetlist within the recursive routine...) + * While we are at it, build a list of the acceptable GROUP BY + * expressions for use by check_ungrouped_columns() (this avoids + * repeated scans of the targetlist within the recursive routine...) */ foreach(tl, qry->groupClause) { GroupClause *grpcl = lfirst(tl); - Node *expr; + Node *expr; expr = get_sortgroupclause_expr(grpcl, qry->targetList); if (contain_agg_clause(expr)) @@ -198,16 +204,16 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype, /* * There used to be a really ugly hack for count(*) here. * - * It's gone. Now, the grammar transforms count(*) into count(1), - * which does the right thing. (It didn't use to do the right thing, - * because the optimizer had the wrong ideas about semantics of queries - * without explicit variables. Fixed as of Oct 1999 --- tgl.) + * It's gone. Now, the grammar transforms count(*) into count(1), which + * does the right thing. (It didn't use to do the right thing, + * because the optimizer had the wrong ideas about semantics of + * queries without explicit variables. Fixed as of Oct 1999 --- tgl.) * - * Since "1" never evaluates as null, we currently have no need of - * the "usenulls" flag, but it should be kept around; in fact, we should + * Since "1" never evaluates as null, we currently have no need of the + * "usenulls" flag, but it should be kept around; in fact, we should * extend the pg_aggregate table to let usenulls be specified as an - * attribute of user-defined aggregates. In the meantime, usenulls - * is just always set to "false". + * attribute of user-defined aggregates. In the meantime, usenulls is + * just always set to "false". */ aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple); diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index d2ceac82732..ec33e5c3090 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.58 2000/03/23 07:38:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.59 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,15 +33,16 @@ static char *clauseText[] = {"ORDER BY", "GROUP BY", "DISTINCT ON"}; static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node, - List *tlist, int clause); + List *tlist, int clause); static void parseFromClause(ParseState *pstate, List *frmList); RangeTblEntry *transformTableEntry(ParseState *pstate, RangeVar *r); static List *addTargetToSortList(TargetEntry *tle, List *sortlist, - List *targetlist, char *opname); + List *targetlist, char *opname); static bool exprIsInSortList(Node *expr, List *sortList, List *targetList); #ifndef DISABLE_OUTER_JOINS static Node *transformUsingClause(ParseState *pstate, List *using, List *left, List *right); + #endif @@ -63,8 +64,8 @@ makeRangeTable(ParseState *pstate, List *frmList) * * Note that the target is not marked as either inFromCl or inJoinSet. * For INSERT, we don't want the target to be joined to; it's a - * destination of tuples, not a source. For UPDATE/DELETE, we do - * need to scan or join the target. This will happen without the + * destination of tuples, not a source. For UPDATE/DELETE, we do + * need to scan or join the target. This will happen without the * inJoinSet flag because the planner's preprocess_targetlist() * adds the destination's CTID attribute to the targetlist, and * therefore the destination will be a referenced table even if @@ -94,7 +95,7 @@ setTargetTable(ParseState *pstate, char *relname) Node * -mergeInnerJoinQuals(ParseState *pstate, Node *clause); + mergeInnerJoinQuals(ParseState *pstate, Node *clause); Node * mergeInnerJoinQuals(ParseState *pstate, Node *clause) @@ -119,7 +120,7 @@ mergeInnerJoinQuals(ParseState *pstate, Node *clause) pstate->p_join_quals = NULL; return (Node *) expr; -} /* mergeInnerJoinQuals() */ +} /* mergeInnerJoinQuals() */ /* * transformWhereClause - @@ -150,12 +151,12 @@ transformWhereClause(ParseState *pstate, Node *clause) #ifndef DISABLE_JOIN_SYNTAX char * -AttrString(Attr *attr); + AttrString(Attr *attr); char * AttrString(Attr *attr) { - Value *val; + Value *val; Assert(length(attr->attrs) == 1); @@ -167,17 +168,18 @@ AttrString(Attr *attr) } List * -ListTableAsAttrs(ParseState *pstate, char *table); + ListTableAsAttrs(ParseState *pstate, char *table); List * ListTableAsAttrs(ParseState *pstate, char *table) { - Attr *attr = expandTable(pstate, table, TRUE); - List *rlist = NIL; - List *col; + Attr *attr = expandTable(pstate, table, TRUE); + List *rlist = NIL; + List *col; foreach(col, attr->attrs) { - Attr *a = makeAttr(table, strVal((Value *) lfirst(col))); + Attr *a = makeAttr(table, strVal((Value *) lfirst(col))); + rlist = lappend(rlist, a); } @@ -185,25 +187,26 @@ ListTableAsAttrs(ParseState *pstate, char *table) } List * -makeUniqueAttrList(List *candidates, List *idents); + makeUniqueAttrList(List *candidates, List *idents); List * makeUniqueAttrList(List *attrs, List *filter) { - List *result = NULL; - List *candidate; + List *result = NULL; + List *candidate; foreach(candidate, attrs) { - List *fmember; - bool match = FALSE; - Attr *cattr = lfirst(candidate); + List *fmember; + bool match = FALSE; + Attr *cattr = lfirst(candidate); Assert(IsA(cattr, Attr)); Assert(length(cattr->attrs) == 1); foreach(fmember, filter) { - Attr *fattr = lfirst(fmember); + Attr *fattr = lfirst(fmember); + Assert(IsA(fattr, Attr)); Assert(length(fattr->attrs) == 1); @@ -222,19 +225,19 @@ makeUniqueAttrList(List *attrs, List *filter) } List * -makeAttrList(Attr *attr); + makeAttrList(Attr *attr); List * makeAttrList(Attr *attr) { - List *result = NULL; + List *result = NULL; - char *name = attr->relname; - List *col; + char *name = attr->relname; + List *col; - foreach (col, attr->attrs) + foreach(col, attr->attrs) { - Attr *newattr = makeAttr(name, strVal((Value *) lfirst(col))); + Attr *newattr = makeAttr(name, strVal((Value *) lfirst(col))); result = lappend(result, newattr); } @@ -247,13 +250,13 @@ makeAttrList(Attr *attr) * with one attribute name per node. */ List * -ExpandAttrs(Attr *attr); + ExpandAttrs(Attr *attr); List * ExpandAttrs(Attr *attr) { - List *col; - char *relname = attr->relname; - List *rlist = NULL; + List *col; + char *relname = attr->relname; + List *rlist = NULL; Assert(attr != NULL); @@ -262,7 +265,7 @@ ExpandAttrs(Attr *attr) foreach(col, attr->attrs) { - Attr *attr = lfirst(col); + Attr *attr = lfirst(col); rlist = lappend(rlist, makeAttr(relname, AttrString(attr))); } @@ -281,18 +284,20 @@ transformUsingClause(ParseState *pstate, List *usingList, List *leftList, List * foreach(using, usingList) { - List *col; - A_Expr *e; + List *col; + A_Expr *e; - Attr *uattr = lfirst(using); - Attr *lattr = NULL, *rattr = NULL; + Attr *uattr = lfirst(using); + Attr *lattr = NULL, + *rattr = NULL; - /* find the first instances of this column in the shape list - * and the last table in the shape list... + /* + * find the first instances of this column in the shape list and + * the last table in the shape list... */ - foreach (col, leftList) + foreach(col, leftList) { - Attr *attr = lfirst(col); + Attr *attr = lfirst(col); if (strcmp(AttrString(attr), AttrString(uattr)) == 0) { @@ -300,9 +305,9 @@ transformUsingClause(ParseState *pstate, List *usingList, List *leftList, List * break; } } - foreach (col, rightList) + foreach(col, rightList) { - Attr *attr = lfirst(col); + Attr *attr = lfirst(col); if (strcmp(AttrString(attr), AttrString(uattr)) == 0) { @@ -334,7 +339,8 @@ transformUsingClause(ParseState *pstate, List *usingList, List *leftList, List * } return ((Node *) transformExpr(pstate, (Node *) expr, EXPR_COLUMN_FIRST)); -} /* transformUsiongClause() */ +} /* transformUsiongClause() */ + #endif @@ -343,9 +349,11 @@ transformTableEntry(ParseState *pstate, RangeVar *r) { RelExpr *baserel = r->relExpr; char *relname = baserel->relname; + #if 0 char *refname; List *columns; + #endif RangeTblEntry *rte; @@ -368,7 +376,7 @@ transformTableEntry(ParseState *pstate, RangeVar *r) if (length(columns) != length(r->name->attrs)) elog(ERROR, "'%s' has %d columns but %d %s specified", relname, length(columns), length(r->name->attrs), - ((length(r->name->attrs) != 1)? "aliases": "alias")); + ((length(r->name->attrs) != 1) ? "aliases" : "alias")); aliasList = nconc(aliasList, r->name->attrs); } @@ -380,9 +388,7 @@ transformTableEntry(ParseState *pstate, RangeVar *r) } } else - { elog(NOTICE, "transformTableEntry: column aliases not handled (internal error)"); - } #else elog(ERROR, "Column aliases not yet supported"); #endif @@ -412,7 +418,7 @@ transformTableEntry(ParseState *pstate, RangeVar *r) baserel->inh, TRUE, TRUE); return rte; -} /* transformTableEntry() */ +} /* transformTableEntry() */ /* @@ -432,7 +438,7 @@ transformTableEntry(ParseState *pstate, RangeVar *r) static void parseFromClause(ParseState *pstate, List *frmList) { - List *fl; + List *fl; foreach(fl, frmList) { @@ -452,17 +458,17 @@ parseFromClause(ParseState *pstate, List *frmList) /* Plain vanilla inner join, just like we've always had? */ if (IsA(n, RangeVar)) - { transformTableEntry(pstate, (RangeVar *) n); - } /* A newfangled join expression? */ else if (IsA(n, JoinExpr)) { #ifndef DISABLE_JOIN_SYNTAX - RangeTblEntry *l_rte, *r_rte; - Attr *l_name, *r_name = NULL; - JoinExpr *j = (JoinExpr *) n; + RangeTblEntry *l_rte, + *r_rte; + Attr *l_name, + *r_name = NULL; + JoinExpr *j = (JoinExpr *) n; if (j->alias != NULL) elog(ERROR, "JOIN table aliases are not supported"); @@ -471,7 +477,7 @@ parseFromClause(ParseState *pstate, List *frmList) if (IsA(j->larg, JoinExpr)) { parseFromClause(pstate, lcons(j->larg, NIL)); - l_name = ((JoinExpr *)j->larg)->alias; + l_name = ((JoinExpr *) j->larg)->alias; } else { @@ -483,7 +489,7 @@ parseFromClause(ParseState *pstate, List *frmList) if (IsA(j->rarg, JoinExpr)) { parseFromClause(pstate, lcons(j->rarg, NIL)); - l_name = ((JoinExpr *)j->larg)->alias; + l_name = ((JoinExpr *) j->larg)->alias; } else { @@ -492,25 +498,30 @@ parseFromClause(ParseState *pstate, List *frmList) r_name = expandTable(pstate, r_rte->eref->relname, TRUE); } - /* Natural join does not explicitly specify columns; must generate columns to join. - * Need to run through the list of columns from each table or join result - * and match up the column names. Use the first table, and check every - * column in the second table for a match. + /* + * Natural join does not explicitly specify columns; must + * generate columns to join. Need to run through the list of + * columns from each table or join result and match up the + * column names. Use the first table, and check every column + * in the second table for a match. */ if (j->isNatural) { - List *lx, *rx; - List *rlist = NULL; + List *lx, + *rx; + List *rlist = NULL; foreach(lx, l_name->attrs) { - Ident *id = NULL; - Value *l_col = lfirst(lx); + Ident *id = NULL; + Value *l_col = lfirst(lx); + Assert(IsA(l_col, String)); foreach(rx, r_name->attrs) { - Value *r_col = lfirst(rx); + Value *r_col = lfirst(rx); + Assert(IsA(r_col, String)); if (strcmp(strVal(l_col), strVal(r_col)) == 0) @@ -534,30 +545,32 @@ parseFromClause(ParseState *pstate, List *frmList) { /* CROSS JOIN */ if (j->quals == NULL) - { printf("CROSS JOIN...\n"); - } - /* JOIN/USING - * This is an inner join, so rip apart the join node and - * transform into a traditional FROM list. NATURAL JOIN - * and JOIN USING both change the shape of the result. - * Need to generate a list of result columns to use for - * target list expansion and validation. + /* + * JOIN/USING This is an inner join, so rip apart the join + * node and transform into a traditional FROM list. + * NATURAL JOIN and JOIN USING both change the shape of + * the result. Need to generate a list of result columns + * to use for target list expansion and validation. */ else if (IsA(j->quals, List)) { + /* - * List of Ident nodes means column names from a real USING - * clause. Determine the shape of the joined table. + * List of Ident nodes means column names from a real + * USING clause. Determine the shape of the joined + * table. */ - List *ucols, *ucol; - List *shape = NULL; - List *alias = NULL; - List *l_shape, *r_shape; + List *ucols, + *ucol; + List *shape = NULL; + List *alias = NULL; + List *l_shape, + *r_shape; - List *l_cols = makeAttrList(l_name); - List *r_cols = makeAttrList(r_name); + List *l_cols = makeAttrList(l_name); + List *r_cols = makeAttrList(r_name); printf("USING input tables are:\n %s\n %s\n", nodeToString(l_name), nodeToString(r_name)); @@ -566,14 +579,15 @@ parseFromClause(ParseState *pstate, List *frmList) nodeToString(l_cols), nodeToString(r_cols)); /* Columns from the USING clause... */ - ucols = (List *)j->quals; + ucols = (List *) j->quals; foreach(ucol, ucols) { - List *col; - Attr *l_attr = NULL, *r_attr = NULL; - Ident *id = lfirst(ucol); + List *col; + Attr *l_attr = NULL, + *r_attr = NULL; + Ident *id = lfirst(ucol); - Attr *attr = makeAttr("", id->name); + Attr *attr = makeAttr("", id->name); foreach(col, l_cols) { @@ -634,9 +648,7 @@ parseFromClause(ParseState *pstate, List *frmList) /* otherwise, must be an expression from an ON clause... */ else - { j->quals = (List *) lcons(j->quals, NIL); - } pstate->p_join_quals = (Node *) j->quals; @@ -654,24 +666,22 @@ parseFromClause(ParseState *pstate, List *frmList) #if 0 /* merge qualified join clauses... */ - if (j->quals != NULL) - { - if (*qual != NULL) + if (j->quals != NULL) { - A_Expr *a = makeNode(A_Expr); + if (*qual != NULL) + { + A_Expr *a = makeNode(A_Expr); - a->oper = AND; - a->opname = NULL; - a->lexpr = (Node *) *qual; - a->rexpr = (Node *) j->quals; + a->oper = AND; + a->opname = NULL; + a->lexpr = (Node *) *qual; + a->rexpr = (Node *) j->quals; - *qual = (Node *)a; - } - else - { - *qual = (Node *)j->quals; + *qual = (Node *) a; + } + else + *qual = (Node *) j->quals; } - } #endif #if 0 @@ -688,8 +698,8 @@ parseFromClause(ParseState *pstate, List *frmList) * then we will need to replace the node with two nodes. * Will need access to the previous list item to change * the link pointer to reference these new nodes. Try - * accumulating and returning a new list. - * - thomas 1999-01-08 Not doing this yet though! + * accumulating and returning a new list. - thomas + * 1999-01-08 Not doing this yet though! */ } @@ -708,7 +718,7 @@ parseFromClause(ParseState *pstate, List *frmList) elog(ERROR, "parseFromClause: unexpected FROM clause node (internal error)" "\n\t%s", nodeToString(n)); } -} /* parseFromClause() */ +} /* parseFromClause() */ /* @@ -733,17 +743,17 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) * Handle two special cases as mandated by the SQL92 spec: * * 1. Bare ColumnName (no qualifier or subscripts) - * For a bare identifier, we search for a matching column name - * in the existing target list. Multiple matches are an error + * For a bare identifier, we search for a matching column name + * in the existing target list. Multiple matches are an error * unless they refer to identical values; for example, - * we allow SELECT a, a FROM table ORDER BY a - * but not SELECT a AS b, b FROM table ORDER BY b + * we allow SELECT a, a FROM table ORDER BY a + * but not SELECT a AS b, b FROM table ORDER BY b * If no match is found, we fall through and treat the identifier * as an expression. * For GROUP BY, it is incorrect to match the grouping item against * targetlist entries: according to SQL92, an identifier in GROUP BY * is a reference to a column name exposed by FROM, not to a target - * list column. However, many implementations (including pre-7.0 + * list column. However, many implementations (including pre-7.0 * PostgreSQL) accept this anyway. So for GROUP BY, we look first * to see if the identifier matches any FROM column name, and only * try for a targetlist name if it doesn't. This ensures that we @@ -768,19 +778,21 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) * an expression. *---------- */ - if (IsA(node, Ident) && ((Ident *) node)->indirection == NIL) + if (IsA(node, Ident) &&((Ident *) node)->indirection == NIL) { char *name = ((Ident *) node)->name; if (clause == GROUP_CLAUSE) { + /* * In GROUP BY, we must prefer a match against a FROM-clause - * column to one against the targetlist. Look to see if there is - * a matching column. If so, fall through to let transformExpr() - * do the rest. NOTE: if name could refer ambiguously to more - * than one column name exposed by FROM, colnameRangeTableEntry - * will elog(ERROR). That's just what we want here. + * column to one against the targetlist. Look to see if there + * is a matching column. If so, fall through to let + * transformExpr() do the rest. NOTE: if name could refer + * ambiguously to more than one column name exposed by FROM, + * colnameRangeTableEntry will elog(ERROR). That's just what + * we want here. */ if (colnameRangeTableEntry(pstate, name) != NULL) name = NULL; @@ -798,7 +810,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) { if (target_result != NULL) { - if (! equal(target_result->expr, tle->expr)) + if (!equal(target_result->expr, tle->expr)) elog(ERROR, "%s '%s' is ambiguous", clauseText[clause], name); } @@ -808,7 +820,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) } } if (target_result != NULL) - return target_result; /* return the first match */ + return target_result; /* return the first match */ } } if (IsA(node, A_Const)) @@ -817,7 +829,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) int targetlist_pos = 0; int target_pos; - if (! IsA(val, Integer)) + if (!IsA(val, Integer)) elog(ERROR, "Non-integer constant in %s", clauseText[clause]); target_pos = intVal(val); foreach(tl, tlist) @@ -828,7 +840,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) if (!resnode->resjunk) { if (++targetlist_pos == target_pos) - return tle; /* return the unique match */ + return tle; /* return the unique match */ } } elog(ERROR, "%s position %d is not in target list", @@ -836,12 +848,12 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) } /* - * Otherwise, we have an expression (this is a Postgres extension - * not found in SQL92). Convert the untransformed node to a - * transformed expression, and search for a match in the tlist. - * NOTE: it doesn't really matter whether there is more than one - * match. Also, we are willing to match a resjunk target here, - * though the above cases must ignore resjunk targets. + * Otherwise, we have an expression (this is a Postgres extension not + * found in SQL92). Convert the untransformed node to a transformed + * expression, and search for a match in the tlist. NOTE: it doesn't + * really matter whether there is more than one match. Also, we are + * willing to match a resjunk target here, though the above cases must + * ignore resjunk targets. */ expr = transformExpr(pstate, node, EXPR_COLUMN_FIRST); @@ -855,8 +867,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) /* * If no matches, construct a new target entry which is appended to - * the end of the target list. This target is given resjunk = TRUE - * so that it will not be projected into the final tuple. + * the end of the target list. This target is given resjunk = TRUE so + * that it will not be projected into the final tuple. */ target_result = transformTargetEntry(pstate, node, expr, NULL, true); lappend(tlist, target_result); @@ -884,7 +896,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist) targetlist, GROUP_CLAUSE); /* avoid making duplicate grouplist entries */ - if (! exprIsInSortList(tle->expr, glist, targetlist)) + if (!exprIsInSortList(tle->expr, glist, targetlist)) { GroupClause *grpcl = makeNode(GroupClause); @@ -915,8 +927,8 @@ transformSortClause(ParseState *pstate, foreach(olitem, orderlist) { - SortGroupBy *sortby = lfirst(olitem); - TargetEntry *tle; + SortGroupBy *sortby = lfirst(olitem); + TargetEntry *tle; tle = findTargetlistEntry(pstate, sortby->node, targetlist, ORDER_CLAUSE); @@ -933,7 +945,7 @@ transformSortClause(ParseState *pstate, * transform a DISTINCT or DISTINCT ON clause * * Since we may need to add items to the query's sortClause list, that list - * is passed by reference. We might also need to add items to the query's + * is passed by reference. We might also need to add items to the query's * targetlist, but we assume that cannot be empty initially, so we can * lappend to it even though the pointer is passed by value. */ @@ -955,10 +967,10 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, /* * All non-resjunk elements from target list that are not already - * in the sort list should be added to it. (We don't really care + * in the sort list should be added to it. (We don't really care * what order the DISTINCT fields are checked in, so we can leave - * the user's ORDER BY spec alone, and just add additional sort keys - * to it to ensure that all targetlist items get sorted.) + * the user's ORDER BY spec alone, and just add additional sort + * keys to it to ensure that all targetlist items get sorted.) */ *sortClause = addAllTargetsToSortList(*sortClause, targetlist); @@ -966,8 +978,8 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, * Now, DISTINCT list consists of all non-resjunk sortlist items. * Actually, all the sortlist items had better be non-resjunk! * Otherwise, user wrote SELECT DISTINCT with an ORDER BY item - * that does not appear anywhere in the SELECT targetlist, and - * we can't implement that with only one sorting pass... + * that does not appear anywhere in the SELECT targetlist, and we + * can't implement that with only one sorting pass... */ foreach(slitem, *sortClause) { @@ -988,11 +1000,12 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, * If the user writes both DISTINCT ON and ORDER BY, then the two * expression lists must match (until one or the other runs out). * Otherwise the ORDER BY requires a different sort order than the - * DISTINCT does, and we can't implement that with only one sort pass - * (and if we do two passes, the results will be rather unpredictable). - * However, it's OK to have more DISTINCT ON expressions than ORDER BY - * expressions; we can just add the extra DISTINCT values to the sort - * list, much as we did above for ordinary DISTINCT fields. + * DISTINCT does, and we can't implement that with only one sort + * pass (and if we do two passes, the results will be rather + * unpredictable). However, it's OK to have more DISTINCT ON + * expressions than ORDER BY expressions; we can just add the + * extra DISTINCT values to the sort list, much as we did above + * for ordinary DISTINCT fields. * * Actually, it'd be OK for the common prefixes of the two lists to * match in any order, but implementing that check seems like more @@ -1020,7 +1033,9 @@ transformDistinctClause(ParseState *pstate, List *distinctlist, { *sortClause = addTargetToSortList(tle, *sortClause, targetlist, NULL); - /* Probably, the tle should always have been added at the + + /* + * Probably, the tle should always have been added at the * end of the sort list ... but search to be safe. */ foreach(slitem, *sortClause) @@ -1059,7 +1074,7 @@ addAllTargetsToSortList(List *sortlist, List *targetlist) { TargetEntry *tle = (TargetEntry *) lfirst(i); - if (! tle->resdom->resjunk) + if (!tle->resdom->resjunk) sortlist = addTargetToSortList(tle, sortlist, targetlist, NULL); } return sortlist; @@ -1078,7 +1093,7 @@ addTargetToSortList(TargetEntry *tle, List *sortlist, List *targetlist, char *opname) { /* avoid making duplicate sortlist entries */ - if (! exprIsInSortList(tle->expr, sortlist, targetlist)) + if (!exprIsInSortList(tle->expr, sortlist, targetlist)) { SortClause *sortcl = makeNode(SortClause); @@ -1109,14 +1124,14 @@ assignSortGroupRef(TargetEntry *tle, List *tlist) Index maxRef; List *l; - if (tle->resdom->ressortgroupref) /* already has one? */ + if (tle->resdom->ressortgroupref) /* already has one? */ return tle->resdom->ressortgroupref; /* easiest way to pick an unused refnumber: max used + 1 */ maxRef = 0; foreach(l, tlist) { - Index ref = ((TargetEntry *) lfirst(l))->resdom->ressortgroupref; + Index ref = ((TargetEntry *) lfirst(l))->resdom->ressortgroupref; if (ref > maxRef) maxRef = ref; @@ -1250,4 +1265,5 @@ transformUnionClause(List *unionClause, List *targetlist) else return NIL; } + #endif diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 26b6934b3d5..880a849f2d8 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.41 2000/04/08 19:29:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.42 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -47,21 +47,22 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, } else if (inputTypeId == UNKNOWNOID && IsA(node, Const)) { + /* * Input is a string constant with previously undetermined type. - * Apply the target type's typinput function to it to produce - * a constant of the target type. + * Apply the target type's typinput function to it to produce a + * constant of the target type. * * NOTE: this case cannot be folded together with the other * constant-input case, since the typinput function does not - * necessarily behave the same as a type conversion function. - * For example, int4's typinput function will reject "1.2", - * whereas float-to-int type conversion will round to integer. + * necessarily behave the same as a type conversion function. For + * example, int4's typinput function will reject "1.2", whereas + * float-to-int type conversion will round to integer. * - * XXX if the typinput function is not cachable, we really ought - * to postpone evaluation of the function call until runtime. - * But there is no way to represent a typinput function call as - * an expression tree, because C-string values are not Datums. + * XXX if the typinput function is not cachable, we really ought to + * postpone evaluation of the function call until runtime. But + * there is no way to represent a typinput function call as an + * expression tree, because C-string values are not Datums. */ Const *con = (Const *) node; Const *newcon = makeNode(Const); @@ -73,10 +74,11 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, newcon->constisnull = con->constisnull; newcon->constisset = false; - if (! con->constisnull) + if (!con->constisnull) { /* We know the source constant is really of type 'text' */ char *val = textout((text *) con->constvalue); + newcon->constvalue = stringTypeDatum(targetType, val, atttypmod); pfree(val); } @@ -85,15 +87,17 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, } else if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId)) { + /* - * We don't really need to do a conversion, but we do need to attach - * a RelabelType node so that the expression will be seen to have - * the intended type when inspected by higher-level code. + * We don't really need to do a conversion, but we do need to + * attach a RelabelType node so that the expression will be seen + * to have the intended type when inspected by higher-level code. */ RelabelType *relabel = makeNode(RelabelType); relabel->arg = node; relabel->resulttype = targetTypeId; + /* * XXX could we label result with exprTypmod(node) instead of * default -1 typmod, to save a possible length-coercion later? @@ -111,11 +115,12 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, } else { + /* * Otherwise, find the appropriate type conversion function - * (caller should have determined that there is one), and - * generate an expression tree representing run-time - * application of the conversion function. + * (caller should have determined that there is one), and generate + * an expression tree representing run-time application of the + * conversion function. */ FuncCall *n = makeNode(FuncCall); Type targetType = typeidType(targetTypeId); @@ -135,20 +140,20 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, /* * If the input is a constant, apply the type conversion function - * now instead of delaying to runtime. (We could, of course, - * just leave this to be done during planning/optimization; - * but it's a very frequent special case, and we save cycles - * in the rewriter if we fold the expression now.) + * now instead of delaying to runtime. (We could, of course, just + * leave this to be done during planning/optimization; but it's a + * very frequent special case, and we save cycles in the rewriter + * if we fold the expression now.) * - * Note that no folding will occur if the conversion function is - * not marked 'iscachable'. + * Note that no folding will occur if the conversion function is not + * marked 'iscachable'. * - * HACK: if constant is NULL, don't fold it here. This is needed - * by make_subplan(), which calls this routine on placeholder Const - * nodes that mustn't be collapsed. (It'd be a lot cleaner to make - * a separate node type for that purpose...) + * HACK: if constant is NULL, don't fold it here. This is needed by + * make_subplan(), which calls this routine on placeholder Const + * nodes that mustn't be collapsed. (It'd be a lot cleaner to + * make a separate node type for that purpose...) */ - if (IsA(node, Const) && ! ((Const *) node)->constisnull) + if (IsA(node, Const) &&!((Const *) node)->constisnull) result = eval_const_expressions(result); } @@ -181,8 +186,8 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids) /* run through argument list... */ for (i = 0; i < nargs; i++) { - Oid inputTypeId = input_typeids[i]; - Oid targetTypeId = func_typeids[i]; + Oid inputTypeId = input_typeids[i]; + Oid targetTypeId = func_typeids[i]; /* no problem if same type */ if (inputTypeId == targetTypeId) @@ -203,8 +208,8 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids) return false; /* - * If input is an untyped string constant, assume we can - * convert it to anything except a class type. + * If input is an untyped string constant, assume we can convert + * it to anything except a class type. */ if (inputTypeId == UNKNOWNOID) { @@ -220,15 +225,15 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids) continue; /* - * Else, try for explicit conversion using functions: - * look for a single-argument function named with the - * target type name and accepting the source type. + * Else, try for explicit conversion using functions: look for a + * single-argument function named with the target type name and + * accepting the source type. */ MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid)); oid_array[0] = inputTypeId; ftup = SearchSysCacheTuple(PROCNAME, - PointerGetDatum(typeidTypeName(targetTypeId)), + PointerGetDatum(typeidTypeName(targetTypeId)), Int32GetDatum(1), PointerGetDatum(oid_array), 0); @@ -331,14 +336,14 @@ TypeCategory(Oid inType) result = STRING_TYPE; break; - /* - * Kluge added 4/8/00 by tgl: treat the new BIT types as strings, - * so that 'unknown' || 'unknown' continues to resolve as textcat - * rather than generating an ambiguous-operator error. Probably - * BIT types should have their own type category, or maybe they - * should be numeric? Need a better way of handling unknown types - * first. - */ + /* + * Kluge added 4/8/00 by tgl: treat the new BIT types as + * strings, so that 'unknown' || 'unknown' continues to + * resolve as textcat rather than generating an + * ambiguous-operator error. Probably BIT types should have + * their own type category, or maybe they should be numeric? + * Need a better way of handling unknown types first. + */ case (ZPBITOID): case (VARBITOID): result = STRING_TYPE; diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 12c10988dfe..0bb81dd2475 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.75 2000/03/19 07:13:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.76 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,17 +33,17 @@ #include "utils/syscache.h" -int max_expr_depth = DEFAULT_MAX_EXPR_DEPTH; +int max_expr_depth = DEFAULT_MAX_EXPR_DEPTH; static int expr_depth_counter = 0; static Node *parser_typecast_constant(Value *expr, TypeName *typename); static Node *parser_typecast_expression(ParseState *pstate, - Node *expr, TypeName *typename); + Node *expr, TypeName *typename); static Node *transformAttr(ParseState *pstate, Attr *att, int precedence); static Node *transformIdent(ParseState *pstate, Ident *ident, int precedence); static Node *transformIndirection(ParseState *pstate, Node *basenode, - List *indirection); + List *indirection); /* @@ -92,8 +92,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) return NULL; /* - * Guard against an overly complex expression leading to coredump - * due to stack overflow here, or in later recursive routines that + * Guard against an overly complex expression leading to coredump due + * to stack overflow here, or in later recursive routines that * traverse expression trees. Note that this is very unlikely to * happen except with pathological queries; but we don't want someone * to be able to crash the backend quite that easily... @@ -172,7 +172,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) "nullvalue", lcons(lexpr, NIL), false, false, - &pstate->p_last_resno, + &pstate->p_last_resno, precedence); } break; @@ -184,7 +184,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) "nonnullvalue", lcons(lexpr, NIL), false, false, - &pstate->p_last_resno, + &pstate->p_last_resno, precedence); } break; @@ -289,7 +289,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) if (sublink->subLinkType == EXISTS_SUBLINK) { - /* EXISTS needs no lefthand or combining operator. + + /* + * EXISTS needs no lefthand or combining operator. * These fields should be NIL already, but make sure. */ sublink->lefthand = NIL; @@ -299,7 +301,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) { List *tlist = qtree->targetList; - /* Make sure the subselect delivers a single column + /* + * Make sure the subselect delivers a single column * (ignoring resjunk targets). */ if (tlist == NIL || @@ -307,11 +310,13 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) elog(ERROR, "Subselect must have a field"); while ((tlist = lnext(tlist)) != NIL) { - if (! ((TargetEntry *) lfirst(tlist))->resdom->resjunk) + if (!((TargetEntry *) lfirst(tlist))->resdom->resjunk) elog(ERROR, "Subselect must have only one field"); } - /* EXPR needs no lefthand or combining operator. - * These fields should be NIL already, but make sure. + + /* + * EXPR needs no lefthand or combining operator. These + * fields should be NIL already, but make sure. */ sublink->lefthand = NIL; sublink->oper = NIL; @@ -336,10 +341,12 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) sublink->oper = NIL; - /* Scan subquery's targetlist to find values that will be - * matched against lefthand values. We need to ignore - * resjunk targets, so doing the outer iteration over - * right_list is easier than doing it over left_list. + /* + * Scan subquery's targetlist to find values that will + * be matched against lefthand values. We need to + * ignore resjunk targets, so doing the outer + * iteration over right_list is easier than doing it + * over left_list. */ while (right_list != NIL) { @@ -370,8 +377,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) op, typeidTypeName(opform->oprresult), typeidTypeName(BOOLOID)); - newop = makeOper(oprid(optup),/* opno */ - InvalidOid, /* opid */ + newop = makeOper(oprid(optup), /* opno */ + InvalidOid, /* opid */ opform->oprresult, 0, NULL); @@ -453,9 +460,10 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) || ((TypeCategory(wtype) == USER_TYPE) && (TypeCategory(c->casetype) == USER_TYPE))) { + /* - * both types in different categories? - * then not much hope... + * both types in different categories? then + * not much hope... */ elog(ERROR, "CASE/WHEN types '%s' and '%s' not matched", typeidTypeName(c->casetype), typeidTypeName(wtype)); @@ -463,9 +471,10 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) else if (IsPreferredType(pcategory, wtype) && can_coerce_type(1, &ptype, &wtype)) { + /* - * new one is preferred and can convert? - * then take it... + * new one is preferred and can convert? then + * take it... */ ptype = wtype; pcategory = TypeCategory(ptype); @@ -478,6 +487,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) { if (!c->casetype || c->casetype == UNKNOWNOID) { + /* * default clause is NULL, so assign preferred * type from WHEN clauses... @@ -553,14 +563,14 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) break; } - /* - * Quietly accept node types that may be presented when we are called - * on an already-transformed tree. - * - * Do any other node types need to be accepted? For now we are taking - * a conservative approach, and only accepting node types that are - * demonstrably necessary to accept. - */ + /* + * Quietly accept node types that may be presented when we are + * called on an already-transformed tree. + * + * Do any other node types need to be accepted? For now we are + * taking a conservative approach, and only accepting node + * types that are demonstrably necessary to accept. + */ case T_Expr: case T_Var: case T_Const: @@ -610,7 +620,10 @@ transformIdent(ParseState *pstate, Ident *ident, int precedence) Node *result = NULL; RangeTblEntry *rte; - /* try to find the ident as a relation ... but not if subscripts appear */ + /* + * try to find the ident as a relation ... but not if subscripts + * appear + */ if (ident->indirection == NIL && refnameRangeTableEntry(pstate, ident->name) != NULL) { @@ -625,6 +638,7 @@ transformIdent(ParseState *pstate, Ident *ident, int precedence) { /* Convert it to a fully qualified Attr, and transform that */ Attr *att = makeAttr(rte->eref->relname, ident->name); + att->indirection = ident->indirection; return transformAttr(pstate, att, precedence); } @@ -687,7 +701,7 @@ exprType(Node *expr) Query *qtree = (Query *) sublink->subselect; TargetEntry *tent; - if (! qtree || ! IsA(qtree, Query)) + if (!qtree || !IsA(qtree, Query)) elog(ERROR, "Cannot get type for untransformed sublink"); tent = (TargetEntry *) lfirst(qtree->targetList); type = tent->resdom->restype; @@ -735,11 +749,12 @@ exprTypmod(Node *expr) case T_Const: { /* Be smart about string constants... */ - Const *con = (Const *) expr; + Const *con = (Const *) expr; + switch (con->consttype) { case BPCHAROID: - if (! con->constisnull) + if (!con->constisnull) return VARSIZE(DatumGetPointer(con->constvalue)); break; default: @@ -749,7 +764,7 @@ exprTypmod(Node *expr) break; case T_Expr: { - int32 coercedTypmod; + int32 coercedTypmod; /* Be smart about length-coercion functions... */ if (exprIsLengthCoercion(expr, &coercedTypmod)) @@ -794,7 +809,7 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) /* Is it a function-call at all? */ if (expr == NULL || - ! IsA(expr, Expr) || + !IsA(expr, Expr) || ((Expr *) expr)->opType != FUNC_EXPR) return false; func = (Func *) (((Expr *) expr)->oper); @@ -802,12 +817,13 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) /* * If it's not a two-argument function with the second argument being - * an int4 constant, it can't have been created from a length coercion. + * an int4 constant, it can't have been created from a length + * coercion. */ if (length(((Expr *) expr)->args) != 2) return false; second_arg = (Const *) lsecond(((Expr *) expr)->args); - if (! IsA(second_arg, Const) || + if (!IsA(second_arg, Const) || second_arg->consttype != INT4OID || second_arg->constisnull) return false; @@ -823,9 +839,9 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) procStruct = (Form_pg_proc) GETSTRUCT(tup); /* - * It must be a function with two arguments where the first is of - * the same type as the return value and the second is an int4. - * Also, just to be sure, check return type agrees with expr node. + * It must be a function with two arguments where the first is of the + * same type as the return value and the second is an int4. Also, just + * to be sure, check return type agrees with expr node. */ if (procStruct->pronargs != 2 || procStruct->prorettype != procStruct->proargtypes[0] || @@ -834,8 +850,8 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) return false; /* - * Furthermore, the name of the function must be the same - * as the argument/result type's name. + * Furthermore, the name of the function must be the same as the + * argument/result type's name. */ tup = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(procStruct->prorettype), @@ -891,7 +907,7 @@ parser_typecast_constant(Value *expr, TypeName *typename) if (typename->arrayBounds != NIL) { - char type_string[NAMEDATALEN+2]; + char type_string[NAMEDATALEN + 2]; sprintf(type_string, "_%s", typename->name); tp = (Type) typenameType(type_string); @@ -936,7 +952,7 @@ parser_typecast_expression(ParseState *pstate, if (typename->arrayBounds != NIL) { - char type_string[NAMEDATALEN+2]; + char type_string[NAMEDATALEN + 2]; sprintf(type_string, "_%s", typename->name); tp = (Type) typenameType(type_string); @@ -957,9 +973,10 @@ parser_typecast_expression(ParseState *pstate, typeidTypeName(inputType), typeidTypeName(targetType)); } + /* - * If the target is a fixed-length type, it may need a length - * coercion as well as a type coercion. + * If the target is a fixed-length type, it may need a length coercion + * as well as a type coercion. */ expr = coerce_type_typmod(pstate, expr, targetType, typename->typmod); diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 67d5aea77ad..3b543c3d613 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.77 2000/03/23 07:38:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.78 2000/04/12 17:15:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -45,13 +45,14 @@ static Oid **argtype_inherit(int nargs, Oid *oid_array); static int find_inheritors(Oid relid, Oid **supervec); static CandidateList func_get_candidates(char *funcname, int nargs); -static bool func_get_detail(char *funcname, - int nargs, - Oid *oid_array, - Oid *funcid, /* return value */ - Oid *rettype, /* return value */ - bool *retset, /* return value */ - Oid **true_typeids); +static bool +func_get_detail(char *funcname, + int nargs, + Oid *oid_array, + Oid *funcid, /* return value */ + Oid *rettype, /* return value */ + bool *retset, /* return value */ + Oid **true_typeids); static Oid **gen_cross_product(InhPaths *arginh, int nargs); static void make_arguments(ParseState *pstate, int nargs, @@ -127,7 +128,7 @@ agg_get_candidates(char *aggname, HeapTuple tup; Form_pg_aggregate agg; int ncandidates = 0; - ScanKeyData aggKey[1]; + ScanKeyData aggKey[1]; *candidates = NULL; @@ -179,8 +180,8 @@ agg_select_candidate(Oid typeid, CandidateList candidates) current_category; /* - * First look for exact matches or binary compatible matches. - * (Of course exact matches shouldn't even get here, but anyway.) + * First look for exact matches or binary compatible matches. (Of + * course exact matches shouldn't even get here, but anyway.) */ ncandidates = 0; last_candidate = NULL; @@ -191,18 +192,18 @@ agg_select_candidate(Oid typeid, CandidateList candidates) current_typeid = current_candidate->args[0]; if (current_typeid == typeid - || IS_BINARY_COMPATIBLE(current_typeid, typeid)) + || IS_BINARY_COMPATIBLE(current_typeid, typeid)) { last_candidate = current_candidate; ncandidates++; - } - } + } + } if (ncandidates == 1) return last_candidate->args[0]; /* - * If no luck that way, look for candidates which allow coercion - * and have a preferred type. Keep all candidates if none match. + * If no luck that way, look for candidates which allow coercion and + * have a preferred type. Keep all candidates if none match. */ category = TypeCategory(typeid); ncandidates = 0; @@ -290,11 +291,11 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, if (nargs == 1 && !must_be_agg) { /* Is it a plain Relation name from the parser? */ - if (IsA(first_arg, Ident) && ((Ident *) first_arg)->isRel) + if (IsA(first_arg, Ident) &&((Ident *) first_arg)->isRel) { Ident *ident = (Ident *) first_arg; RangeTblEntry *rte; - AttrNumber attnum; + AttrNumber attnum; /* * first arg is a relation. This could be a projection. @@ -308,9 +309,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, makeAttr(refname, NULL), FALSE, FALSE, TRUE); #ifdef WARN_FROM - elog(NOTICE,"Adding missing FROM-clause entry%s for table %s", - pstate->parentParseState != NULL ? " in subquery" : "", - refname); + elog(NOTICE, "Adding missing FROM-clause entry%s for table %s", + pstate->parentParseState != NULL ? " in subquery" : "", + refname); #endif } @@ -320,35 +321,39 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, /* * If the attr isn't a set, just make a var for it. If it is - * a set, treat it like a function and drop through. - * Look through the explicit column list first, since we - * now allow column aliases. - * - thomas 2000-02-07 + * a set, treat it like a function and drop through. Look + * through the explicit column list first, since we now allow + * column aliases. - thomas 2000-02-07 */ if (rte->eref->attrs != NULL) { - List *c; - /* start counting attributes/columns from one. - * zero is reserved for InvalidAttrNumber. - * - thomas 2000-01-27 + List *c; + + /* + * start counting attributes/columns from one. zero is + * reserved for InvalidAttrNumber. - thomas 2000-01-27 */ - int i = 1; - foreach (c, rte->eref->attrs) + int i = 1; + + foreach(c, rte->eref->attrs) { - char *colname = strVal(lfirst(c)); + char *colname = strVal(lfirst(c)); + /* found a match? */ if (strcmp(colname, funcname) == 0) { - char *basename = get_attname(relid, i); + char *basename = get_attname(relid, i); if (basename != NULL) { funcname = basename; attnum = i; } - /* attnum was initialized to InvalidAttrNumber - * earlier, so no need to reset it if the - * above test fails. - thomas 2000-02-07 + + /* + * attnum was initialized to InvalidAttrNumber + * earlier, so no need to reset it if the above + * test fails. - thomas 2000-02-07 */ break; } @@ -358,9 +363,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, attnum = specialAttNum(funcname); } else - { attnum = get_attnum(relid, funcname); - } if (attnum != InvalidAttrNumber) { @@ -373,6 +376,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, } else if (ISCOMPLEX(exprType(first_arg))) { + /* * Attempt to handle projection of a complex argument. If * ParseComplexProjection can't handle the projection, we have @@ -411,6 +415,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, if (nargs == 1 || must_be_agg) { + /* * See if it's an aggregate. */ @@ -423,8 +428,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, elog(ERROR, "Aggregate functions may only have one parameter"); /* - * the aggregate COUNT is a special case, ignore its base - * type. Treat it as zero. XXX mighty ugly --- FIXME + * the aggregate COUNT is a special case, ignore its base type. + * Treat it as zero. XXX mighty ugly --- FIXME */ if (strcmp(funcname, "count") == 0) basetype = 0; @@ -469,6 +474,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, if (must_be_agg) { + /* * No matching agg, but we had '*' or DISTINCT, so a plain * function could not have been meant. @@ -491,7 +497,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, { Node *arg = lfirst(i); - if (IsA(arg, Ident) && ((Ident *) arg)->isRel) + if (IsA(arg, Ident) &&((Ident *) arg)->isRel) { RangeTblEntry *rte; int vnum; @@ -509,9 +515,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, makeAttr(refname, NULL), FALSE, FALSE, TRUE); #ifdef WARN_FROM - elog(NOTICE,"Adding missing FROM-clause entry%s for table %s", - pstate->parentParseState != NULL ? " in subquery" : "", - refname); + elog(NOTICE, "Adding missing FROM-clause entry%s for table %s", + pstate->parentParseState != NULL ? " in subquery" : "", + refname); #endif } @@ -532,17 +538,16 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, lfirst(i) = makeVar(vnum, 0, toid, -1, sublevels_up); } else if (!attisset) - { toid = exprType(arg); - } else { /* if attisset is true, we already set toid for the single arg */ } - /* Most of the rest of the parser just assumes that functions do not - * have more than FUNC_MAX_ARGS parameters. We have to test here - * to protect against array overruns, etc. + /* + * Most of the rest of the parser just assumes that functions do + * not have more than FUNC_MAX_ARGS parameters. We have to test + * here to protect against array overruns, etc. */ if (nargs >= FUNC_MAX_ARGS) elog(ERROR, "Cannot pass more than %d arguments to a function", @@ -585,23 +590,26 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, &rettype, &retset, &true_oid_array); if (!exists) { + /* - * If we can't find a function (or can't find a unique function), - * see if this is really a type-coercion request: single-argument - * function call where the function name is a type name. If so, - * and if we can do the coercion trivially, just go ahead and do - * it without requiring there to be a real function for it. + * If we can't find a function (or can't find a unique + * function), see if this is really a type-coercion request: + * single-argument function call where the function name is a + * type name. If so, and if we can do the coercion trivially, + * just go ahead and do it without requiring there to be a + * real function for it. * * "Trivial" coercions are ones that involve binary-compatible * types and ones that are coercing a previously-unknown-type * literal constant to a specific type. * * DO NOT try to generalize this code to nontrivial coercions, - * because you'll just set up an infinite recursion between this - * routine and coerce_type! We have already failed to find a - * suitable "real" coercion function, so we have to fail unless - * this is a coercion that coerce_type can handle by itself. - * Make sure this code stays in sync with what coerce_type does! + * because you'll just set up an infinite recursion between + * this routine and coerce_type! We have already failed to + * find a suitable "real" coercion function, so we have to + * fail unless this is a coercion that coerce_type can handle + * by itself. Make sure this code stays in sync with what + * coerce_type does! */ if (nargs == 1) { @@ -612,15 +620,17 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, 0, 0, 0); if (HeapTupleIsValid(tp)) { - Oid sourceType = oid_array[0]; - Oid targetType = typeTypeId(tp); - Node *arg1 = lfirst(fargs); + Oid sourceType = oid_array[0]; + Oid targetType = typeTypeId(tp); + Node *arg1 = lfirst(fargs); if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) || sourceType == targetType || IS_BINARY_COMPATIBLE(sourceType, targetType)) { - /* Ah-hah, we can do it as a trivial coercion. + + /* + * Ah-hah, we can do it as a trivial coercion. * coerce_type can handle these cases, so why * duplicate code... */ @@ -640,7 +650,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, */ if (nargs == 1) { - Type tp = typeidType(oid_array[0]); + Type tp = typeidType(oid_array[0]); + if (typeTypeFlag(tp) == 'c') elog(ERROR, "No such attribute or function '%s'", funcname); @@ -911,8 +922,8 @@ func_select_candidate(int nargs, current_type; /* - * Run through all candidates and keep those with the most matches - * on exact types. Keep all candidates if none match. + * Run through all candidates and keep those with the most matches on + * exact types. Keep all candidates if none match. */ ncandidates = 0; nbestMatch = 0; @@ -955,10 +966,9 @@ func_select_candidate(int nargs, return candidates->args; /* - * Still too many candidates? - * Run through all candidates and keep those with the most matches - * on exact types + binary-compatible types. - * Keep all candidates if none match. + * Still too many candidates? Run through all candidates and keep + * those with the most matches on exact types + binary-compatible + * types. Keep all candidates if none match. */ ncandidates = 0; nbestMatch = 0; @@ -1005,10 +1015,9 @@ func_select_candidate(int nargs, return candidates->args; /* - * Still too many candidates? - * Now look for candidates which are preferred types at the args that - * will require coercion. - * Keep all candidates if none match. + * Still too many candidates? Now look for candidates which are + * preferred types at the args that will require coercion. Keep all + * candidates if none match. */ ncandidates = 0; nbestMatch = 0; @@ -1052,19 +1061,19 @@ func_select_candidate(int nargs, return candidates->args; /* - * Still too many candidates? - * Try assigning types for the unknown columns. + * Still too many candidates? Try assigning types for the unknown + * columns. * - * We do this by examining each unknown argument position to see if all the - * candidates agree on the type category of that slot. If so, and if some - * candidates accept the preferred type in that category, eliminate the - * candidates with other input types. If we are down to one candidate - * at the end, we win. + * We do this by examining each unknown argument position to see if all + * the candidates agree on the type category of that slot. If so, and + * if some candidates accept the preferred type in that category, + * eliminate the candidates with other input types. If we are down to + * one candidate at the end, we win. * * XXX It's kinda bogus to do this left-to-right, isn't it? If we - * eliminate some candidates because they are non-preferred at the first - * slot, we won't notice that they didn't have the same type category for - * a later slot. + * eliminate some candidates because they are non-preferred at the + * first slot, we won't notice that they didn't have the same type + * category for a later slot. */ for (i = 0; i < nargs; i++) { @@ -1117,7 +1126,7 @@ func_select_candidate(int nargs, last_candidate = current_candidate; } } - if (last_candidate) /* terminate rebuilt list */ + if (last_candidate) /* terminate rebuilt list */ last_candidate->next = NULL; } } @@ -1174,7 +1183,11 @@ func_get_detail(char *funcname, } else { - /* didn't find an exact match, so now try to match up candidates... */ + + /* + * didn't find an exact match, so now try to match up + * candidates... + */ CandidateList function_typeids; function_typeids = func_get_candidates(funcname, nargs); @@ -1234,7 +1247,9 @@ func_get_detail(char *funcname, 0); Assert(HeapTupleIsValid(ftup)); } - /* otherwise, ambiguous function call, so fail by + + /* + * otherwise, ambiguous function call, so fail by * exiting loop with ftup still NULL. */ break; @@ -1242,7 +1257,8 @@ func_get_detail(char *funcname, /* * No match here, so try the next inherited type vector. - * First time through, we need to compute the list of vectors. + * First time through, we need to compute the list of + * vectors. */ if (input_typeid_vector == NULL) input_typeid_vector = argtype_inherit(nargs, oid_array); @@ -1341,10 +1357,10 @@ find_inheritors(Oid relid, Oid **supervec) /* * Use queue to do a breadth-first traversal of the inheritance graph - * from the relid supplied up to the root. At the top of the loop, - * relid is the OID of the reltype to check next, queue is the list - * of pending rels to check after this one, and visited is the list - * of relids we need to output. + * from the relid supplied up to the root. At the top of the loop, + * relid is the OID of the reltype to check next, queue is the list of + * pending rels to check after this one, and visited is the list of + * relids we need to output. */ do { @@ -1372,7 +1388,7 @@ find_inheritors(Oid relid, Oid **supervec) { relid = lfirsti(queue); queue = lnext(queue); - if (! intMember(relid, visited)) + if (!intMember(relid, visited)) { newrelid = true; break; @@ -1401,7 +1417,7 @@ find_inheritors(Oid relid, Oid **supervec) relid = lfirsti(elt); rd = heap_open(relid, NoLock); - if (! RelationIsValid(rd)) + if (!RelationIsValid(rd)) elog(ERROR, "Relid %u does not exist", relid); trelid = typeTypeId(typenameType(RelationGetRelationName(rd))); heap_close(rd, NoLock); @@ -1412,7 +1428,9 @@ find_inheritors(Oid relid, Oid **supervec) *supervec = (Oid *) NULL; freeList(visited); - /* there doesn't seem to be any equally easy way to release the queue + + /* + * there doesn't seem to be any equally easy way to release the queue * list cells, but since they're palloc'd space it's not critical. */ diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 2d365db91d5..0f386b84c71 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.38 2000/02/24 01:59:17 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.39 2000/04/12 17:15:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -225,7 +225,7 @@ make_var(ParseState *pstate, Oid relid, char *refname, * * In an array assignment, we are given a destination array value plus a * source value that is to be assigned to a single element or a slice of - * that array. We produce an expression that represents the new array value + * that array. We produce an expression that represents the new array value * with the source data inserted into the right part of the array. * * pstate Parse state @@ -234,7 +234,7 @@ make_var(ParseState *pstate, Oid relid, char *refname, * forceSlice If true, treat subscript as array slice in all cases * assignFrom NULL for array fetch, else transformed expression for source. */ -ArrayRef * +ArrayRef * transformArraySubscripts(ParseState *pstate, Node *arrayBase, List *indirection, @@ -281,19 +281,19 @@ transformArraySubscripts(ParseState *pstate, /* * A list containing only single subscripts refers to a single array * element. If any of the items are double subscripts (lower:upper), - * then the subscript expression means an array slice operation. - * In this case, we supply a default lower bound of 1 for any items - * that contain only a single subscript. - * The forceSlice parameter forces us to treat the operation as a - * slice, even if no lower bounds are mentioned. Otherwise, - * we have to prescan the indirection list to see if there are any - * double subscripts. + * then the subscript expression means an array slice operation. In + * this case, we supply a default lower bound of 1 for any items that + * contain only a single subscript. The forceSlice parameter forces us + * to treat the operation as a slice, even if no lower bounds are + * mentioned. Otherwise, we have to prescan the indirection list to + * see if there are any double subscripts. */ - if (! isSlice) + if (!isSlice) { - foreach (idx, indirection) + foreach(idx, indirection) { A_Indices *ai = (A_Indices *) lfirst(idx); + if (ai->lidx != NULL) { isSlice = true; @@ -302,9 +302,10 @@ transformArraySubscripts(ParseState *pstate, } } - /* The type represented by the subscript expression is the element type - * if we are fetching a single element, but it is the same as the array - * type if we are fetching a slice or storing. + /* + * The type represented by the subscript expression is the element + * type if we are fetching a single element, but it is the same as the + * array type if we are fetching a slice or storing. */ if (isSlice || assignFrom != NULL) typeresult = typearray; @@ -314,7 +315,7 @@ transformArraySubscripts(ParseState *pstate, /* * Transform the subscript expressions. */ - foreach (idx, indirection) + foreach(idx, indirection) { A_Indices *ai = (A_Indices *) lfirst(idx); Node *subexpr; @@ -337,7 +338,7 @@ transformArraySubscripts(ParseState *pstate, sizeof(int32), Int32GetDatum(1), false, - true, /* pass by value */ + true, /* pass by value */ false, false); } @@ -371,7 +372,7 @@ transformArraySubscripts(ParseState *pstate, if (assignFrom == NULL) elog(ERROR, "Array assignment requires type '%s'" " but expression is of type '%s'" - "\n\tYou will need to rewrite or cast the expression", + "\n\tYou will need to rewrite or cast the expression", typeidTypeName(typeneeded), typeidTypeName(typesource)); } @@ -384,7 +385,8 @@ transformArraySubscripts(ParseState *pstate, aref = makeNode(ArrayRef); aref->refattrlength = type_struct_array->typlen; aref->refelemlength = type_struct_element->typlen; - aref->refelemtype = typeresult; /* XXX should save element type too */ + aref->refelemtype = typeresult; /* XXX should save element type + * too */ aref->refelembyval = type_struct_element->typbyval; aref->refupperindexpr = upperIndexpr; aref->reflowerindexpr = lowerIndexpr; @@ -407,7 +409,7 @@ transformArraySubscripts(ParseState *pstate, * resolution that we're not sure that it should be considered text. * Explicit "NULL" constants are also typed as UNKNOWN. * - * For integers and floats we produce int4, float8, or numeric depending + * For integers and floats we produce int4, float8, or numeric depending * on the value of the number. XXX In some cases it would be nice to take * context into account when determining the type to convert to, but in * other cases we can't delay the type choice. One possibility is to invent @@ -462,7 +464,7 @@ make_const(Value *value) case T_String: val = PointerGetDatum(textin(strVal(value))); - typeid = UNKNOWNOID; /* will be coerced later */ + typeid = UNKNOWNOID;/* will be coerced later */ typelen = -1; /* variable len */ typebyval = false; break; @@ -496,7 +498,7 @@ make_const(Value *value) /* * Decide whether a T_Float value fits in float8, or must be treated as - * type "numeric". We check the number of digits and check for overflow/ + * type "numeric". We check the number of digits and check for overflow/ * underflow. (With standard compilation options, Postgres' NUMERIC type * can handle decimal exponents up to 1000, considerably more than most * implementations of float8, so this is a sensible test.) @@ -504,9 +506,9 @@ make_const(Value *value) static bool fitsInFloat(Value *value) { - const char *ptr; - int ndigits; - char *endptr; + const char *ptr; + int ndigits; + char *endptr; /* * Count digits, ignoring leading zeroes (but not trailing zeroes). @@ -525,6 +527,7 @@ fitsInFloat(Value *value) } if (ndigits > DBL_DIG) return false; + /* * Use strtod() to check for overflow/underflow. */ diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index fd41f4f3a0f..2a9de556b26 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.39 2000/03/19 00:19:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.40 2000/04/12 17:15:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -29,10 +29,10 @@ static Oid *oper_select_candidate(int nargs, Oid *input_typeids, static Operator oper_exact(char *op, Oid arg1, Oid arg2); static Operator oper_inexact(char *op, Oid arg1, Oid arg2); static int binary_oper_get_candidates(char *opname, - CandidateList *candidates); + CandidateList *candidates); static int unary_oper_get_candidates(char *opname, - CandidateList *candidates, - char rightleft); + CandidateList *candidates, + char rightleft); static void op_error(char *op, Oid arg1, Oid arg2); static void unary_op_error(char *op, Oid arg, bool is_left_op); @@ -229,8 +229,8 @@ oper_select_candidate(int nargs, return candidates->args; /* - * Run through all candidates and keep those with the most matches - * on exact types. Keep all candidates if none match. + * Run through all candidates and keep those with the most matches on + * exact types. Keep all candidates if none match. */ ncandidates = 0; nbestMatch = 0; @@ -273,10 +273,9 @@ oper_select_candidate(int nargs, return candidates->args; /* - * Still too many candidates? - * Run through all candidates and keep those with the most matches - * on exact types + binary-compatible types. - * Keep all candidates if none match. + * Still too many candidates? Run through all candidates and keep + * those with the most matches on exact types + binary-compatible + * types. Keep all candidates if none match. */ ncandidates = 0; nbestMatch = 0; @@ -323,10 +322,9 @@ oper_select_candidate(int nargs, return candidates->args; /* - * Still too many candidates? - * Now look for candidates which are preferred types at the args that - * will require coercion. - * Keep all candidates if none match. + * Still too many candidates? Now look for candidates which are + * preferred types at the args that will require coercion. Keep all + * candidates if none match. */ ncandidates = 0; nbestMatch = 0; @@ -370,15 +368,16 @@ oper_select_candidate(int nargs, return candidates->args; /* - * Still too many candidates? - * Try assigning types for the unknown columns. + * Still too many candidates? Try assigning types for the unknown + * columns. * * First try: if we have an unknown and a non-unknown input, see whether - * there is a candidate all of whose input types are the same as the known - * input type (there can be at most one such candidate). If so, use that - * candidate. NOTE that this is cool only because operators can't - * have more than 2 args, so taking the last non-unknown as current_type - * can yield only one possibility if there is also an unknown. + * there is a candidate all of whose input types are the same as the + * known input type (there can be at most one such candidate). If so, + * use that candidate. NOTE that this is cool only because operators + * can't have more than 2 args, so taking the last non-unknown as + * current_type can yield only one possibility if there is also an + * unknown. */ unknownOids = FALSE; current_type = UNKNOWNOID; @@ -410,16 +409,16 @@ oper_select_candidate(int nargs, } /* - * Second try: examine each unknown argument position to see if all the - * candidates agree on the type category of that slot. If so, and if some - * candidates accept the preferred type in that category, eliminate the - * candidates with other input types. If we are down to one candidate - * at the end, we win. + * Second try: examine each unknown argument position to see if all + * the candidates agree on the type category of that slot. If so, and + * if some candidates accept the preferred type in that category, + * eliminate the candidates with other input types. If we are down to + * one candidate at the end, we win. * * XXX It's kinda bogus to do this left-to-right, isn't it? If we - * eliminate some candidates because they are non-preferred at the first - * slot, we won't notice that they didn't have the same type category for - * a later slot. + * eliminate some candidates because they are non-preferred at the + * first slot, we won't notice that they didn't have the same type + * category for a later slot. */ for (i = 0; i < nargs; i++) { @@ -472,7 +471,7 @@ oper_select_candidate(int nargs, last_candidate = current_candidate; } } - if (last_candidate) /* terminate rebuilt list */ + if (last_candidate) /* terminate rebuilt list */ last_candidate->next = NULL; } } @@ -588,9 +587,7 @@ oper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings) { } else if (!noWarnings) - { op_error(opname, ltypeId, rtypeId); - } return (Operator) tup; } /* oper() */ @@ -679,14 +676,12 @@ right_oper(char *op, Oid arg) /* Try for inexact matches */ ncandidates = unary_oper_get_candidates(op, &candidates, 'r'); if (ncandidates == 0) - { unary_op_error(op, arg, FALSE); - } else if (ncandidates == 1) { tup = SearchSysCacheTuple(OPERNAME, PointerGetDatum(op), - ObjectIdGetDatum(candidates->args[0]), + ObjectIdGetDatum(candidates->args[0]), ObjectIdGetDatum(InvalidOid), CharGetDatum('r')); } @@ -731,15 +726,13 @@ left_oper(char *op, Oid arg) /* Try for inexact matches */ ncandidates = unary_oper_get_candidates(op, &candidates, 'l'); if (ncandidates == 0) - { unary_op_error(op, arg, TRUE); - } else if (ncandidates == 1) { tup = SearchSysCacheTuple(OPERNAME, PointerGetDatum(op), ObjectIdGetDatum(InvalidOid), - ObjectIdGetDatum(candidates->args[0]), + ObjectIdGetDatum(candidates->args[0]), CharGetDatum('l')); } else diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 76c79de6c6d..4bb65cf27e8 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.39 2000/03/23 07:38:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.40 2000/04/12 17:15:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -76,7 +76,7 @@ static char *attnum_type[SPECIALS] = { * - thomas 2000-03-04 */ List * -refnameRangeTableEntries(ParseState *pstate, char *refname); + refnameRangeTableEntries(ParseState *pstate, char *refname); List * refnameRangeTableEntries(ParseState *pstate, char *refname) @@ -119,7 +119,7 @@ refnameRangeTableEntry(ParseState *pstate, char *refname) } /* given refname, return RT index (starting with 1) of the relation, - * and optionally get its nesting depth (0 = current). If sublevels_up + * and optionally get its nesting depth (0 = current). If sublevels_up * is NULL, only consider rels at the current nesting level. */ int @@ -179,8 +179,9 @@ colnameRangeTableEntry(ParseState *pstate, char *colname) if (rte->eref->attrs != NULL) { - List *c; - foreach (c, rte->ref->attrs) + List *c; + + foreach(c, rte->ref->attrs) { if (strcmp(strVal(lfirst(c)), colname) == 0) { @@ -192,16 +193,14 @@ colnameRangeTableEntry(ParseState *pstate, char *colname) } } - /* Even if we have an attribute list in the RTE, - * look for the column here anyway. This is the only - * way we will find implicit columns like "oid". - * - thomas 2000-02-07 + /* + * Even if we have an attribute list in the RTE, look for the + * column here anyway. This is the only way we will find + * implicit columns like "oid". - thomas 2000-02-07 */ if ((rte_candidate == NULL) && (get_attnum(rte->relid, colname) != InvalidAttrNumber)) - { rte_candidate = rte; - } if (rte_candidate == NULL) continue; @@ -236,18 +235,18 @@ addRangeTableEntry(ParseState *pstate, bool inFromCl, bool inJoinSet) { - Relation rel; - RangeTblEntry *rte; - Attr *eref; - int maxattrs; - int sublevels_up; - int varattno; + Relation rel; + RangeTblEntry *rte; + Attr *eref; + int maxattrs; + int sublevels_up; + int varattno; /* Look for an existing rte, if available... */ if (pstate != NULL) { - int rt_index = refnameRangeTablePosn(pstate, ref->relname, - &sublevels_up); + int rt_index = refnameRangeTablePosn(pstate, ref->relname, + &sublevels_up); if (rt_index != 0 && (!inFromCl || sublevels_up == 0)) { @@ -262,12 +261,11 @@ addRangeTableEntry(ParseState *pstate, rte->relname = relname; rte->ref = ref; - /* Get the rel's OID. This access also ensures that we have an - * up-to-date relcache entry for the rel. We don't need to keep - * it open, however. - * Since this is open anyway, let's check that the number of column - * aliases is reasonable. - * - Thomas 2000-02-04 + /* + * Get the rel's OID. This access also ensures that we have an + * up-to-date relcache entry for the rel. We don't need to keep it + * open, however. Since this is open anyway, let's check that the + * number of column aliases is reasonable. - Thomas 2000-02-04 */ rel = heap_openr(relname, AccessShareLock); rte->relid = RelationGetRelid(rel); @@ -290,10 +288,9 @@ addRangeTableEntry(ParseState *pstate, rte->eref = eref; /* - * Flags: - * - this RTE should be expanded to include descendant tables, - * - this RTE is in the FROM clause, - * - this RTE should be included in the planner's final join. + * Flags: - this RTE should be expanded to include descendant tables, + * - this RTE is in the FROM clause, - this RTE should be included in + * the planner's final join. */ rte->inh = inh; rte->inFromCl = inFromCl; @@ -318,18 +315,16 @@ addRangeTableEntry(ParseState *pstate, Attr * expandTable(ParseState *pstate, char *refname, bool getaliases) { - Attr *attr; - RangeTblEntry *rte; - Relation rel; + Attr *attr; + RangeTblEntry *rte; + Relation rel; int varattno, maxattrs; rte = refnameRangeTableEntry(pstate, refname); if (getaliases && (rte != NULL)) - { return rte->eref; - } if (rte != NULL) rel = heap_open(rte->relid, AccessShareLock); @@ -350,7 +345,7 @@ expandTable(ParseState *pstate, char *refname, bool getaliases) #ifdef _DROP_COLUMN_HACK__ if (COLUMN_IS_DROPPED(rel->rd_att->attrs[varattno])) continue; -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname)); attr->attrs = lappend(attr->attrs, makeString(attrname)); } @@ -367,11 +362,11 @@ expandTable(ParseState *pstate, char *refname, bool getaliases) List * expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno) { - List *te_list = NIL; - RangeTblEntry *rte; - Relation rel; - int varattno, - maxattrs; + List *te_list = NIL; + RangeTblEntry *rte; + Relation rel; + int varattno, + maxattrs; rte = refnameRangeTableEntry(pstate, ref->relname); if (rte == NULL) @@ -379,9 +374,9 @@ expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno) rte = addRangeTableEntry(pstate, relname, ref, FALSE, FALSE, TRUE); #ifdef WARN_FROM - elog(NOTICE,"Adding missing FROM-clause entry%s for table %s", - pstate->parentParseState != NULL ? " in subquery" : "", - refname); + elog(NOTICE, "Adding missing FROM-clause entry%s for table %s", + pstate->parentParseState != NULL ? " in subquery" : "", + refname); #endif } @@ -391,18 +386,21 @@ expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno) for (varattno = 0; varattno < maxattrs; varattno++) { - char *attrname; - char *label; - Var *varnode; - TargetEntry *te = makeNode(TargetEntry); + char *attrname; + char *label; + Var *varnode; + TargetEntry *te = makeNode(TargetEntry); #ifdef _DROP_COLUMN_HACK__ if (COLUMN_IS_DROPPED(rel->rd_att->attrs[varattno])) continue; -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname)); - /* varattno is zero-based, so check that length() is always greater */ + /* + * varattno is zero-based, so check that length() is always + * greater + */ if (length(rte->eref->attrs) > varattno) label = pstrdup(strVal(nth(varattno, rte->eref->attrs))); else @@ -452,7 +450,7 @@ attnameAttNum(Relation rd, char *a) /* on failure */ elog(ERROR, "Relation '%s' does not have attribute '%s'", RelationGetRelationName(rd), a); - return InvalidAttrNumber; /* lint */ + return InvalidAttrNumber; /* lint */ } /* specialAttNum() @@ -528,8 +526,3 @@ attnumTypeId(Relation rd, int attid) */ return rd->rd_att->attrs[attid - 1]->atttypid; } - - - - - diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 65a5b33d58c..d8ba6aedb7d 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.57 2000/03/14 23:06:33 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.58 2000/04/12 17:15:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -61,7 +61,9 @@ transformTargetEntry(ParseState *pstate, if (colname == NULL) { - /* Generate a suitable column name for a column without any + + /* + * Generate a suitable column name for a column without any * explicit 'AS ColumnName' clause. */ colname = FigureColname(expr, node); @@ -101,14 +103,16 @@ transformTargetList(ParseState *pstate, List *targetlist) if (att->relname != NULL && strcmp(att->relname, "*") == 0) { + /* - * Target item is a single '*', expand all tables - * (eg. SELECT * FROM emp) + * Target item is a single '*', expand all tables (eg. + * SELECT * FROM emp) */ if (pstate->p_shape != NULL) { - List *s, *a; - int i; + List *s, + *a; + int i; Assert(length(pstate->p_shape) == length(pstate->p_alias)); @@ -116,12 +120,12 @@ transformTargetList(ParseState *pstate, List *targetlist) a = pstate->p_alias; for (i = 0; i < length(pstate->p_shape); i++) { - TargetEntry *te; - char *colname; - Attr *shape = lfirst(s); - Attr *alias = lfirst(a); + TargetEntry *te; + char *colname; + Attr *shape = lfirst(s); + Attr *alias = lfirst(a); - Assert(IsA(shape, Attr) && IsA(alias, Attr)); + Assert(IsA(shape, Attr) &&IsA(alias, Attr)); colname = strVal(lfirst(alias->attrs)); te = transformTargetEntry(pstate, (Node *) shape, @@ -138,9 +142,10 @@ transformTargetList(ParseState *pstate, List *targetlist) else if (att->attrs != NIL && strcmp(strVal(lfirst(att->attrs)), "*") == 0) { + /* - * Target item is relation.*, expand that table - * (eg. SELECT emp.*, dname FROM emp, dept) + * Target item is relation.*, expand that table (eg. + * SELECT emp.*, dname FROM emp, dept) */ p_target = nconc(p_target, expandAll(pstate, att->relname, @@ -178,7 +183,7 @@ transformTargetList(ParseState *pstate, List *targetlist) /* * updateTargetListEntry() - * This is used in INSERT and UPDATE statements only. It prepares a + * This is used in INSERT and UPDATE statements only. It prepares a * TargetEntry for assignment to a column of the target table. * This includes coercing the given value to the target column's type * (if necessary), and dealing with any subscripts attached to the target @@ -197,7 +202,7 @@ updateTargetListEntry(ParseState *pstate, int attrno, List *indirection) { - Oid type_id = exprType(tle->expr); /* type of value provided */ + Oid type_id = exprType(tle->expr); /* type of value provided */ Oid attrtype; /* type of target column */ int32 attrtypmod; Resdom *resnode = tle->resdom; @@ -210,18 +215,20 @@ updateTargetListEntry(ParseState *pstate, attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod; /* - * If there are subscripts on the target column, prepare an - * array assignment expression. This will generate an array value - * that the source value has been inserted into, which can then - * be placed in the new tuple constructed by INSERT or UPDATE. - * Note that transformArraySubscripts takes care of type coercion. + * If there are subscripts on the target column, prepare an array + * assignment expression. This will generate an array value that the + * source value has been inserted into, which can then be placed in + * the new tuple constructed by INSERT or UPDATE. Note that + * transformArraySubscripts takes care of type coercion. */ if (indirection) { #ifndef DISABLE_JOIN_SYNTAX Attr *att = makeAttr(pstrdup(RelationGetRelationName(rd)), colname); + #else Attr *att = makeNode(Attr); + #endif Node *arrayBase; ArrayRef *aref; @@ -239,24 +246,26 @@ updateTargetListEntry(ParseState *pstate, tle->expr); if (pstate->p_is_insert) { + /* * The command is INSERT INTO table (arraycol[subscripts]) ... * so there is not really a source array value to work with. - * Let the executor do something reasonable, if it can. - * Notice that we forced transformArraySubscripts to treat - * the subscripting op as an array-slice op above, so the - * source data will have been coerced to array type. + * Let the executor do something reasonable, if it can. Notice + * that we forced transformArraySubscripts to treat the + * subscripting op as an array-slice op above, so the source + * data will have been coerced to array type. */ - aref->refexpr = NULL; /* signal there is no source array */ + aref->refexpr = NULL; /* signal there is no source array */ } tle->expr = (Node *) aref; } else { + /* - * For normal non-subscripted target column, do type checking - * and coercion. But accept InvalidOid, which indicates the - * source is a NULL constant. + * For normal non-subscripted target column, do type checking and + * coercion. But accept InvalidOid, which indicates the source is + * a NULL constant. */ if (type_id != InvalidOid) { @@ -267,11 +276,12 @@ updateTargetListEntry(ParseState *pstate, if (tle->expr == NULL) elog(ERROR, "Attribute '%s' is of type '%s'" " but expression is of type '%s'" - "\n\tYou will need to rewrite or cast the expression", + "\n\tYou will need to rewrite or cast the expression", colname, typeidTypeName(attrtype), typeidTypeName(type_id)); } + /* * If the target is a fixed-length type, it may need a length * coercion as well as a type coercion. @@ -282,9 +292,10 @@ updateTargetListEntry(ParseState *pstate, } /* - * The result of the target expression should now match the destination - * column's type. Also, reset the resname and resno to identify - * the destination column --- rewriter and planner depend on that! + * The result of the target expression should now match the + * destination column's type. Also, reset the resname and resno to + * identify the destination column --- rewriter and planner depend on + * that! */ resnode->restype = attrtype; resnode->restypmod = attrtypmod; @@ -344,6 +355,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos) if (cols == NIL) { + /* * Generate default column list for INSERT. */ @@ -357,20 +369,19 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos) #ifdef _DROP_COLUMN_HACK__ if (COLUMN_IS_DROPPED(attr[i])) - { continue; - } -#endif /* _DROP_COLUMN_HACK__ */ +#endif /* _DROP_COLUMN_HACK__ */ id->name = palloc(NAMEDATALEN); StrNCpy(id->name, NameStr(attr[i]->attname), NAMEDATALEN); id->indirection = NIL; id->isRel = false; cols = lappend(cols, id); - *attrnos = lappendi(*attrnos, i+1); + *attrnos = lappendi(*attrnos, i + 1); } } else { + /* * Do initial validation of user-supplied INSERT column list. */ @@ -407,6 +418,7 @@ ExpandAllTables(ParseState *pstate) rtable = pstate->p_rtable; if (pstate->p_is_rule) { + /* * skip first two entries, "*new*" and "*current*" */ @@ -422,9 +434,9 @@ ExpandAllTables(ParseState *pstate) RangeTblEntry *rte = lfirst(rt); /* - * we only expand those listed in the from clause. (This will - * also prevent us from using the wrong table in inserts: eg. - * tenk2 in "insert into tenk2 select * from tenk1;") + * we only expand those listed in the from clause. (This will also + * prevent us from using the wrong table in inserts: eg. tenk2 in + * "insert into tenk2 select * from tenk1;") */ if (!rte->inFromCl) continue; @@ -449,11 +461,12 @@ FigureColname(Node *expr, Node *resval) /* Some of these are easiest to do with the untransformed node */ switch (nodeTag(resval)) { - case T_Ident: + case T_Ident: return ((Ident *) resval)->name; case T_Attr: { List *attrs = ((Attr *) resval)->attrs; + if (attrs) { while (lnext(attrs) != NIL) diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index 488df8a8c9f..a7652407b73 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.44 2000/03/17 05:29:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.45 2000/04/12 17:15:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #if defined(FLEX_SCANNER) extern void DeleteBuffer(void); + #endif /* FLEX_SCANNER */ char *parseString; /* the char* which holds the string to be diff --git a/src/backend/parser/scansup.c b/src/backend/parser/scansup.c index ae05569071d..3a82ee51b77 100644 --- a/src/backend/parser/scansup.c +++ b/src/backend/parser/scansup.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/scansup.c,v 1.18 2000/01/26 05:56:43 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/scansup.c,v 1.19 2000/04/12 17:15:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -44,7 +44,7 @@ scanstr(char *s) len = strlen(s); - newStr = palloc(len+1); /* string cannot get longer */ + newStr = palloc(len + 1); /* string cannot get longer */ for (i = 0, j = 0; i < len; i++) { |