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