mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
pgindent run over code.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: analyze.c,v 1.107 1999/05/23 21:41:14 tgl Exp $
|
||||
* $Id: analyze.c,v 1.108 1999/05/25 16:10:10 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -45,8 +45,8 @@ static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
|
||||
static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
|
||||
static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
|
||||
|
||||
static void transformForUpdate(Query *qry, List *forUpdate);
|
||||
void CheckSelectForUpdate(Query *qry);
|
||||
static void transformForUpdate(Query *qry, List *forUpdate);
|
||||
void CheckSelectForUpdate(Query *qry);
|
||||
|
||||
List *extras_before = NIL;
|
||||
List *extras_after = NIL;
|
||||
@@ -62,9 +62,9 @@ List *extras_after = NIL;
|
||||
List *
|
||||
parse_analyze(List *pl, ParseState *parentParseState)
|
||||
{
|
||||
List *result = NIL;
|
||||
List *result = NIL;
|
||||
ParseState *pstate;
|
||||
Query *parsetree;
|
||||
Query *parsetree;
|
||||
|
||||
while (pl != NIL)
|
||||
{
|
||||
@@ -76,7 +76,7 @@ parse_analyze(List *pl, ParseState *parentParseState)
|
||||
while (extras_before != NIL)
|
||||
{
|
||||
result = lappend(result,
|
||||
transformStmt(pstate, lfirst(extras_before)));
|
||||
transformStmt(pstate, lfirst(extras_before)));
|
||||
if (pstate->p_target_relation != NULL)
|
||||
heap_close(pstate->p_target_relation);
|
||||
extras_before = lnext(extras_before);
|
||||
@@ -192,8 +192,8 @@ transformStmt(ParseState *pstate, Node *parseTree)
|
||||
if (!((SelectStmt *) parseTree)->portalname)
|
||||
{
|
||||
result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
|
||||
result->limitOffset = ((SelectStmt *)parseTree)->limitOffset;
|
||||
result->limitCount = ((SelectStmt *)parseTree)->limitCount;
|
||||
result->limitOffset = ((SelectStmt *) parseTree)->limitOffset;
|
||||
result->limitCount = ((SelectStmt *) parseTree)->limitCount;
|
||||
}
|
||||
else
|
||||
result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
|
||||
@@ -276,8 +276,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
|
||||
int ndef = pstate->p_target_relation->rd_att->constr->num_defval;
|
||||
|
||||
/*
|
||||
* if stmt->cols == NIL then makeTargetNames returns list of all attrs.
|
||||
* May have to shorten icolumns list...
|
||||
* if stmt->cols == NIL then makeTargetNames returns list of all
|
||||
* attrs. May have to shorten icolumns list...
|
||||
*/
|
||||
if (stmt->cols == NIL)
|
||||
{
|
||||
@@ -286,16 +286,18 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
|
||||
|
||||
foreach(extrl, icolumns)
|
||||
{
|
||||
|
||||
/*
|
||||
* decrements first, so if we started with zero items
|
||||
* it will now be negative
|
||||
* decrements first, so if we started with zero items it
|
||||
* will now be negative
|
||||
*/
|
||||
if (--i <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* this an index into the targetList,
|
||||
* so make sure we had one to start...
|
||||
* this an index into the targetList, so make sure we had one
|
||||
* to start...
|
||||
*/
|
||||
if (i >= 0)
|
||||
{
|
||||
@@ -303,9 +305,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
|
||||
lnext(extrl) = NIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
icolumns = NIL;
|
||||
}
|
||||
}
|
||||
|
||||
while (ndef-- > 0)
|
||||
@@ -378,15 +378,18 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
|
||||
|
||||
/*
|
||||
* The INSERT INTO ... SELECT ... could have a UNION in child, so
|
||||
* unionClause may be false
|
||||
, */
|
||||
qry->unionall = stmt->unionall;
|
||||
* unionClause may be false ,
|
||||
*/
|
||||
qry->unionall = stmt->unionall;
|
||||
|
||||
/***S*I***/
|
||||
/* Just hand through the unionClause and intersectClause.
|
||||
* We will handle it in the function Except_Intersect_Rewrite() */
|
||||
qry->unionClause = stmt->unionClause;
|
||||
qry->intersectClause = stmt->intersectClause;
|
||||
/***S*I***/
|
||||
|
||||
/*
|
||||
* Just hand through the unionClause and intersectClause. We will
|
||||
* handle it in the function Except_Intersect_Rewrite()
|
||||
*/
|
||||
qry->unionClause = stmt->unionClause;
|
||||
qry->intersectClause = stmt->intersectClause;
|
||||
|
||||
/*
|
||||
* If there is a havingQual but there are no aggregates, then there is
|
||||
@@ -508,9 +511,12 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
Constraint *constraint;
|
||||
List *keys;
|
||||
Ident *key;
|
||||
List *blist = NIL; /* "before list" of things to do before creating the table */
|
||||
List *ilist = NIL; /* "index list" of things to do after creating the table */
|
||||
IndexStmt *index, *pkey = NULL;
|
||||
List *blist = NIL; /* "before list" of things to do before
|
||||
* creating the table */
|
||||
List *ilist = NIL; /* "index list" of things to do after
|
||||
* creating the table */
|
||||
IndexStmt *index,
|
||||
*pkey = NULL;
|
||||
IndexElem *iparam;
|
||||
|
||||
q = makeNode(Query);
|
||||
@@ -532,15 +538,15 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
|
||||
if (column->is_sequence)
|
||||
{
|
||||
char *sname;
|
||||
char *cstring;
|
||||
char *sname;
|
||||
char *cstring;
|
||||
CreateSeqStmt *sequence;
|
||||
|
||||
sname = makeTableName(stmt->relname, column->colname, "seq", NULL);
|
||||
if (sname == NULL)
|
||||
elog(ERROR, "CREATE TABLE/SERIAL implicit sequence name must be less than %d characters"
|
||||
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN-5));
|
||||
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN - 5));
|
||||
|
||||
constraint = makeNode(Constraint);
|
||||
constraint->contype = CONSTR_DEFAULT;
|
||||
@@ -560,7 +566,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
if (constraint->name == NULL)
|
||||
elog(ERROR, "CREATE TABLE/SERIAL implicit index name must be less than %d characters"
|
||||
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN-5));
|
||||
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN - 5));
|
||||
column->constraints = lappend(column->constraints, constraint);
|
||||
|
||||
sequence = makeNode(CreateSeqStmt);
|
||||
@@ -582,8 +588,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
switch (constraint->contype)
|
||||
{
|
||||
case CONSTR_NULL:
|
||||
/* We should mark this explicitly,
|
||||
* so we can tell if NULL and NOT NULL are both specified
|
||||
|
||||
/*
|
||||
* We should mark this explicitly, so we
|
||||
* can tell if NULL and NOT NULL are both
|
||||
* specified
|
||||
*/
|
||||
if (column->is_not_null)
|
||||
elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
|
||||
@@ -611,7 +620,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
if (constraint->name == NULL)
|
||||
elog(ERROR, "CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
|
||||
"\n\tLength of '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN-6));
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN - 6));
|
||||
if (constraint->keys == NIL)
|
||||
constraint->keys = lappend(constraint->keys, column);
|
||||
dlist = lappend(dlist, constraint);
|
||||
@@ -623,7 +632,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
if (constraint->name == NULL)
|
||||
elog(ERROR, "CREATE TABLE/UNIQUE implicit index name must be less than %d characters"
|
||||
"\n\tLength of '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN-5));
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN - 5));
|
||||
if (constraint->keys == NIL)
|
||||
constraint->keys = lappend(constraint->keys, column);
|
||||
dlist = lappend(dlist, constraint);
|
||||
@@ -636,7 +645,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
if (constraint->name == NULL)
|
||||
elog(ERROR, "CREATE TABLE/CHECK implicit constraint name must be less than %d characters"
|
||||
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN-1));
|
||||
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN - 1));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -657,8 +666,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
constraint->name = makeTableName(stmt->relname, "pkey", NULL);
|
||||
if (constraint->name == NULL)
|
||||
elog(ERROR, "CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
|
||||
"\n\tLength of '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN-5));
|
||||
"\n\tLength of '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN - 5));
|
||||
dlist = lappend(dlist, constraint);
|
||||
break;
|
||||
|
||||
@@ -704,12 +713,12 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
constraint = lfirst(dlist);
|
||||
Assert(nodeTag(constraint) == T_Constraint);
|
||||
Assert((constraint->contype == CONSTR_PRIMARY)
|
||||
|| (constraint->contype == CONSTR_UNIQUE));
|
||||
|| (constraint->contype == CONSTR_UNIQUE));
|
||||
|
||||
index = makeNode(IndexStmt);
|
||||
|
||||
index->unique = TRUE;
|
||||
index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE:FALSE);
|
||||
index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE : FALSE);
|
||||
if (index->primary)
|
||||
{
|
||||
if (pkey != NULL)
|
||||
@@ -719,21 +728,17 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
}
|
||||
|
||||
if (constraint->name != NULL)
|
||||
{
|
||||
index->idxname = constraint->name;
|
||||
}
|
||||
else if (constraint->contype == CONSTR_PRIMARY)
|
||||
{
|
||||
index->idxname = makeTableName(stmt->relname, "pkey", NULL);
|
||||
if (index->idxname == NULL)
|
||||
elog(ERROR, "CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
|
||||
"\n\tLength of '%s' must be less than %d",
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN-5));
|
||||
NAMEDATALEN, stmt->relname, (NAMEDATALEN - 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
index->idxname = NULL;
|
||||
}
|
||||
|
||||
index->relname = stmt->relname;
|
||||
index->accessMethod = "btree";
|
||||
@@ -793,16 +798,20 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
ilist = NIL;
|
||||
while (dlist != NIL)
|
||||
{
|
||||
int keep = TRUE;
|
||||
int keep = TRUE;
|
||||
|
||||
index = lfirst(dlist);
|
||||
|
||||
/* has a single column argument, so might be a conflicting index... */
|
||||
/*
|
||||
* has a single column argument, so might be a conflicting
|
||||
* index...
|
||||
*/
|
||||
if ((index != pkey)
|
||||
&& (length(index->indexParams) == 1))
|
||||
&& (length(index->indexParams) == 1))
|
||||
{
|
||||
char *pname = ((IndexElem *) lfirst(index->indexParams))->name;
|
||||
char *iname = ((IndexElem *) lfirst(index->indexParams))->name;
|
||||
char *pname = ((IndexElem *) lfirst(index->indexParams))->name;
|
||||
char *iname = ((IndexElem *) lfirst(index->indexParams))->name;
|
||||
|
||||
/* same names? then don't keep... */
|
||||
keep = (strcmp(iname, pname) != 0);
|
||||
}
|
||||
@@ -818,7 +827,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
{
|
||||
index = lfirst(dlist);
|
||||
elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
|
||||
(index->primary? "PRIMARY KEY": "UNIQUE"),
|
||||
(index->primary ? "PRIMARY KEY" : "UNIQUE"),
|
||||
index->idxname, stmt->relname);
|
||||
dlist = lnext(dlist);
|
||||
}
|
||||
@@ -828,7 +837,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
extras_after = ilist;
|
||||
|
||||
return q;
|
||||
} /* transformCreateStmt() */
|
||||
} /* transformCreateStmt() */
|
||||
|
||||
/*
|
||||
* transformIndexStmt -
|
||||
@@ -1006,11 +1015,14 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
*/
|
||||
qry->unionall = stmt->unionall;
|
||||
|
||||
/***S*I***/
|
||||
/* Just hand through the unionClause and intersectClause.
|
||||
* We will handle it in the function Except_Intersect_Rewrite() */
|
||||
qry->unionClause = stmt->unionClause;
|
||||
qry->intersectClause = stmt->intersectClause;
|
||||
/***S*I***/
|
||||
|
||||
/*
|
||||
* Just hand through the unionClause and intersectClause. We will
|
||||
* handle it in the function Except_Intersect_Rewrite()
|
||||
*/
|
||||
qry->unionClause = stmt->unionClause;
|
||||
qry->intersectClause = stmt->intersectClause;
|
||||
|
||||
/*
|
||||
* If there is a havingQual but there are no aggregates, then there is
|
||||
@@ -1092,91 +1104,92 @@ transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
* The built up list is handed back in **select_list.
|
||||
* If one of the SelectStmt Nodes has the 'unionall' flag
|
||||
* set to true *unionall_present hands back 'true' */
|
||||
void
|
||||
void
|
||||
create_select_list(Node *ptr, List **select_list, bool *unionall_present)
|
||||
{
|
||||
if(IsA(ptr, SelectStmt)) {
|
||||
*select_list = lappend(*select_list, ptr);
|
||||
if(((SelectStmt *)ptr)->unionall == TRUE) *unionall_present = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Recursively call for all arguments. A NOT expr has no lexpr! */
|
||||
if (((A_Expr *)ptr)->lexpr != NULL)
|
||||
create_select_list(((A_Expr *)ptr)->lexpr, select_list, unionall_present);
|
||||
create_select_list(((A_Expr *)ptr)->rexpr, select_list, unionall_present);
|
||||
if (IsA(ptr, SelectStmt))
|
||||
{
|
||||
*select_list = lappend(*select_list, ptr);
|
||||
if (((SelectStmt *) ptr)->unionall == TRUE)
|
||||
*unionall_present = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Recursively call for all arguments. A NOT expr has no lexpr! */
|
||||
if (((A_Expr *) ptr)->lexpr != NULL)
|
||||
create_select_list(((A_Expr *) ptr)->lexpr, select_list, unionall_present);
|
||||
create_select_list(((A_Expr *) ptr)->rexpr, select_list, unionall_present);
|
||||
}
|
||||
|
||||
/* Changes the A_Expr Nodes to Expr Nodes and exchanges ANDs and ORs.
|
||||
* The reason for the exchange is easy: We implement INTERSECTs and EXCEPTs
|
||||
* The reason for the exchange is easy: We implement INTERSECTs and EXCEPTs
|
||||
* by rewriting these queries to semantically equivalent queries that use
|
||||
* IN and NOT IN subselects. To be able to use all three operations
|
||||
* (UNIONs INTERSECTs and EXCEPTs) in one complex query we have to
|
||||
* IN and NOT IN subselects. To be able to use all three operations
|
||||
* (UNIONs INTERSECTs and EXCEPTs) in one complex query we have to
|
||||
* translate the queries into Disjunctive Normal Form (DNF). Unfortunately
|
||||
* there is no function 'dnfify' but there is a function 'cnfify'
|
||||
* which produces DNF when we exchange ANDs and ORs before calling
|
||||
* 'cnfify' and exchange them back in the result.
|
||||
*
|
||||
* If an EXCEPT or INTERSECT is present *intersect_present
|
||||
* hands back 'true' */
|
||||
Node *A_Expr_to_Expr(Node *ptr, bool *intersect_present)
|
||||
* hands back 'true' */
|
||||
Node *
|
||||
A_Expr_to_Expr(Node *ptr, bool *intersect_present)
|
||||
{
|
||||
Node *result = NULL;
|
||||
|
||||
switch(nodeTag(ptr))
|
||||
{
|
||||
case T_A_Expr:
|
||||
{
|
||||
A_Expr *a = (A_Expr *)ptr;
|
||||
|
||||
switch (a->oper)
|
||||
{
|
||||
case AND:
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Node *lexpr = A_Expr_to_Expr(((A_Expr *)ptr)->lexpr, intersect_present);
|
||||
Node *rexpr = A_Expr_to_Expr(((A_Expr *)ptr)->rexpr, intersect_present);
|
||||
Node *result = NULL;
|
||||
|
||||
*intersect_present = TRUE;
|
||||
|
||||
expr->typeOid = BOOLOID;
|
||||
expr->opType = OR_EXPR;
|
||||
expr->args = makeList(lexpr, rexpr, -1);
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
}
|
||||
case OR:
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Node *lexpr = A_Expr_to_Expr(((A_Expr *)ptr)->lexpr, intersect_present);
|
||||
Node *rexpr = A_Expr_to_Expr(((A_Expr *)ptr)->rexpr, intersect_present);
|
||||
switch (nodeTag(ptr))
|
||||
{
|
||||
case T_A_Expr:
|
||||
{
|
||||
A_Expr *a = (A_Expr *) ptr;
|
||||
|
||||
expr->typeOid = BOOLOID;
|
||||
expr->opType = AND_EXPR;
|
||||
expr->args = makeList(lexpr, rexpr, -1);
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
}
|
||||
case NOT:
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Node *rexpr = A_Expr_to_Expr(((A_Expr *)ptr)->rexpr, intersect_present);
|
||||
switch (a->oper)
|
||||
{
|
||||
case AND:
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
|
||||
Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
|
||||
|
||||
expr->typeOid = BOOLOID;
|
||||
expr->opType = NOT_EXPR;
|
||||
expr->args = makeList(rexpr, -1);
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
result = ptr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
*intersect_present = TRUE;
|
||||
|
||||
expr->typeOid = BOOLOID;
|
||||
expr->opType = OR_EXPR;
|
||||
expr->args = makeList(lexpr, rexpr, -1);
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
}
|
||||
case OR:
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
|
||||
Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
|
||||
|
||||
expr->typeOid = BOOLOID;
|
||||
expr->opType = AND_EXPR;
|
||||
expr->args = makeList(lexpr, rexpr, -1);
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
}
|
||||
case NOT:
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
|
||||
|
||||
expr->typeOid = BOOLOID;
|
||||
expr->opType = NOT_EXPR;
|
||||
expr->args = makeList(rexpr, -1);
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = ptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1196,7 +1209,7 @@ static void
|
||||
transformForUpdate(Query *qry, List *forUpdate)
|
||||
{
|
||||
List *rowMark = NULL;
|
||||
RowMark *newrm;
|
||||
RowMark *newrm;
|
||||
List *l;
|
||||
Index i;
|
||||
|
||||
@@ -1205,37 +1218,37 @@ transformForUpdate(Query *qry, List *forUpdate)
|
||||
if (lfirst(forUpdate) == NULL) /* all tables */
|
||||
{
|
||||
i = 1;
|
||||
foreach (l, qry->rtable)
|
||||
foreach(l, qry->rtable)
|
||||
{
|
||||
newrm = makeNode(RowMark);
|
||||
newrm->rti = i++;
|
||||
newrm->info = ROW_MARK_FOR_UPDATE|ROW_ACL_FOR_UPDATE;
|
||||
newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
|
||||
rowMark = lappend(rowMark, newrm);
|
||||
}
|
||||
qry->rowMark = nconc(qry->rowMark, rowMark);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (l, forUpdate)
|
||||
foreach(l, forUpdate)
|
||||
{
|
||||
List *l2;
|
||||
List *l3;
|
||||
List *l2;
|
||||
List *l3;
|
||||
|
||||
i = 1;
|
||||
foreach (l2, qry->rtable)
|
||||
foreach(l2, qry->rtable)
|
||||
{
|
||||
if (strcmp(((RangeTblEntry*)lfirst(l2))->refname, lfirst(l)) == 0)
|
||||
if (strcmp(((RangeTblEntry *) lfirst(l2))->refname, lfirst(l)) == 0)
|
||||
{
|
||||
foreach (l3, rowMark)
|
||||
foreach(l3, rowMark)
|
||||
{
|
||||
if (((RowMark*)lfirst(l3))->rti == i) /* duplicate */
|
||||
if (((RowMark *) lfirst(l3))->rti == i) /* duplicate */
|
||||
break;
|
||||
}
|
||||
if (l3 == NULL)
|
||||
{
|
||||
newrm = makeNode(RowMark);
|
||||
newrm->rti = i;
|
||||
newrm->info = ROW_MARK_FOR_UPDATE|ROW_ACL_FOR_UPDATE;
|
||||
newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
|
||||
rowMark = lappend(rowMark, newrm);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.20 1999/05/23 21:41:14 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.21 1999/05/25 16:10:13 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
static bool contain_agg_clause(Node *clause);
|
||||
static bool exprIsAggOrGroupCol(Node *expr, List *groupClause, List *tlist);
|
||||
static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause,
|
||||
List *tlist);
|
||||
static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause,
|
||||
List *tlist);
|
||||
|
||||
/*
|
||||
* contain_agg_clause
|
||||
@@ -106,7 +106,7 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause, List *tlist)
|
||||
List *gl;
|
||||
|
||||
if (expr == NULL || IsA(expr, Const) ||
|
||||
IsA(expr, Param) || IsA(expr, Aggref) ||
|
||||
IsA(expr, Param) ||IsA(expr, Aggref) ||
|
||||
IsA(expr, SubLink)) /* can't handle currently !!! */
|
||||
return TRUE;
|
||||
|
||||
@@ -190,11 +190,11 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
|
||||
Assert(pstate->p_hasAggs || qry->groupClause);
|
||||
|
||||
/*
|
||||
* Aggregates must never appear in WHERE clauses.
|
||||
* (Note this check should appear first to deliver an appropriate
|
||||
* error message; otherwise we are likely to generate the generic
|
||||
* "illegal use of aggregates in target list" message, which is
|
||||
* outright misleading if the problem is in WHERE.)
|
||||
* Aggregates must never appear in WHERE clauses. (Note this check
|
||||
* should appear first to deliver an appropriate error message;
|
||||
* otherwise we are likely to generate the generic "illegal use of
|
||||
* aggregates in target list" message, which is outright misleading if
|
||||
* the problem is in WHERE.)
|
||||
*/
|
||||
if (contain_agg_clause(qry->qual))
|
||||
elog(ERROR, "Aggregates not allowed in WHERE clause");
|
||||
@@ -219,7 +219,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
|
||||
|
||||
if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause, qry->targetList))
|
||||
elog(ERROR,
|
||||
"Illegal use of aggregates or non-group column in HAVING clause");
|
||||
"Illegal use of aggregates or non-group column in HAVING clause");
|
||||
}
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
|
||||
basetype = aggform->aggbasetype;
|
||||
vartype = exprType(lfirst(target));
|
||||
if ((basetype != vartype)
|
||||
&& (! IS_BINARY_COMPATIBLE(basetype, vartype)))
|
||||
&& (!IS_BINARY_COMPATIBLE(basetype, vartype)))
|
||||
{
|
||||
Type tp1,
|
||||
tp2;
|
||||
@@ -321,8 +321,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
|
||||
tp1 = typeidType(basetype);
|
||||
tp2 = typeidType(vartype);
|
||||
elog(ERROR, "Aggregate type mismatch"
|
||||
"\n\t%s() works on %s, not on %s",
|
||||
aggname, typeTypeName(tp1), typeTypeName(tp2));
|
||||
"\n\t%s() works on %s, not on %s",
|
||||
aggname, typeTypeName(tp1), typeTypeName(tp2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.35 1999/05/22 02:55:57 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.36 1999/05/25 16:10:14 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -41,13 +41,14 @@ static TargetEntry *
|
||||
|
||||
static void parseFromClause(ParseState *pstate, List *frmList, Node **qual);
|
||||
|
||||
Attr *makeAttr(char *relname, char *attname);
|
||||
Attr *makeAttr(char *relname, char *attname);
|
||||
|
||||
#ifdef ENABLE_OUTER_JOINS
|
||||
Node *transformUsingClause(ParseState *pstate, List *onList, char *lname, char *rname);
|
||||
Node *transformUsingClause(ParseState *pstate, List *onList, char *lname, char *rname);
|
||||
|
||||
#endif
|
||||
|
||||
char *transformTableEntry(ParseState *pstate, RangeVar *r);
|
||||
char *transformTableEntry(ParseState *pstate, RangeVar *r);
|
||||
|
||||
|
||||
/*
|
||||
@@ -67,16 +68,14 @@ makeRangeTable(ParseState *pstate, char *relname, List *frmList, Node **qual)
|
||||
return;
|
||||
|
||||
if ((refnameRangeTablePosn(pstate, relname, &sublevels_up) == 0)
|
||||
|| (sublevels_up != 0))
|
||||
|| (sublevels_up != 0))
|
||||
rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE);
|
||||
else
|
||||
rte = refnameRangeTableEntry(pstate, relname);
|
||||
|
||||
/* This could only happen for multi-action rules */
|
||||
if (pstate->p_target_relation != NULL)
|
||||
{
|
||||
heap_close(pstate->p_target_relation);
|
||||
}
|
||||
|
||||
pstate->p_target_rangetblentry = rte;
|
||||
pstate->p_target_relation = heap_open(rte->relid);
|
||||
@@ -102,7 +101,8 @@ transformWhereClause(ParseState *pstate, Node *a_expr, Node *o_expr)
|
||||
|
||||
if ((a_expr != NULL) && (o_expr != NULL))
|
||||
{
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
|
||||
a->oper = AND;
|
||||
a->opname = NULL;
|
||||
a->lexpr = o_expr;
|
||||
@@ -110,12 +110,12 @@ transformWhereClause(ParseState *pstate, Node *a_expr, Node *o_expr)
|
||||
expr = a;
|
||||
}
|
||||
else if (o_expr != NULL)
|
||||
expr = (A_Expr *)o_expr;
|
||||
expr = (A_Expr *) o_expr;
|
||||
else
|
||||
expr = (A_Expr *)a_expr;
|
||||
expr = (A_Expr *) a_expr;
|
||||
|
||||
pstate->p_in_where_clause = true;
|
||||
qual = transformExpr(pstate, (Node *)expr, EXPR_COLUMN_FIRST);
|
||||
qual = transformExpr(pstate, (Node *) expr, EXPR_COLUMN_FIRST);
|
||||
pstate->p_in_where_clause = false;
|
||||
|
||||
if (exprType(qual) != BOOLOID)
|
||||
@@ -130,6 +130,7 @@ Attr *
|
||||
makeAttr(char *relname, char *attname)
|
||||
{
|
||||
Attr *a = makeNode(Attr);
|
||||
|
||||
a->relname = relname;
|
||||
a->paramNo = NULL;
|
||||
a->attrs = lcons(makeString(attname), NIL);
|
||||
@@ -149,30 +150,34 @@ transformUsingClause(ParseState *pstate, List *onList, char *lname, char *rname)
|
||||
List *on;
|
||||
Node *qual;
|
||||
|
||||
foreach (on, onList)
|
||||
foreach(on, onList)
|
||||
{
|
||||
qual = lfirst(on);
|
||||
|
||||
/* Ident node means it is just a column name from a real USING clause... */
|
||||
/*
|
||||
* Ident node means it is just a column name from a real USING
|
||||
* clause...
|
||||
*/
|
||||
if (IsA(qual, Ident))
|
||||
{
|
||||
Ident *i = (Ident *)qual;
|
||||
Ident *i = (Ident *) qual;
|
||||
Attr *lattr = makeAttr(lname, i->name);
|
||||
Attr *rattr = makeAttr(rname, i->name);
|
||||
A_Expr *e = makeNode(A_Expr);
|
||||
A_Expr *e = makeNode(A_Expr);
|
||||
|
||||
e->oper = OP;
|
||||
e->opname = "=";
|
||||
e->lexpr = (Node *)lattr;
|
||||
e->rexpr = (Node *)rattr;
|
||||
e->lexpr = (Node *) lattr;
|
||||
e->rexpr = (Node *) rattr;
|
||||
|
||||
if (expr != NULL)
|
||||
{
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
|
||||
a->oper = AND;
|
||||
a->opname = NULL;
|
||||
a->lexpr = (Node *)expr;
|
||||
a->rexpr = (Node *)e;
|
||||
a->lexpr = (Node *) expr;
|
||||
a->rexpr = (Node *) e;
|
||||
expr = a;
|
||||
}
|
||||
else
|
||||
@@ -184,21 +189,21 @@ transformUsingClause(ParseState *pstate, List *onList, char *lname, char *rname)
|
||||
{
|
||||
if (expr != NULL)
|
||||
{
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
|
||||
a->oper = AND;
|
||||
a->opname = NULL;
|
||||
a->lexpr = (Node *)expr;
|
||||
a->rexpr = (Node *)qual;
|
||||
a->lexpr = (Node *) expr;
|
||||
a->rexpr = (Node *) qual;
|
||||
expr = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
expr = (A_Expr *)qual;
|
||||
}
|
||||
expr = (A_Expr *) qual;
|
||||
}
|
||||
}
|
||||
return ((Node *)transformExpr(pstate, (Node *)expr, EXPR_COLUMN_FIRST));
|
||||
return ((Node *) transformExpr(pstate, (Node *) expr, EXPR_COLUMN_FIRST));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *
|
||||
@@ -213,15 +218,14 @@ transformTableEntry(ParseState *pstate, RangeVar *r)
|
||||
refname = relname;
|
||||
|
||||
/*
|
||||
* marks this entry to indicate it comes from the FROM clause. In
|
||||
* SQL, the target list can only refer to range variables
|
||||
* specified in the from clause but we follow the more powerful
|
||||
* POSTQUEL semantics and automatically generate the range
|
||||
* variable if not specified. However there are times we need to
|
||||
* know whether the entries are legitimate.
|
||||
* marks this entry to indicate it comes from the FROM clause. In SQL,
|
||||
* the target list can only refer to range variables specified in the
|
||||
* from clause but we follow the more powerful POSTQUEL semantics and
|
||||
* automatically generate the range variable if not specified. However
|
||||
* there are times we need to know whether the entries are legitimate.
|
||||
*
|
||||
* eg. select * from foo f where f.x = 1; will generate wrong answer
|
||||
* if we expand * to foo.x.
|
||||
* eg. select * from foo f where f.x = 1; will generate wrong answer if
|
||||
* we expand * to foo.x.
|
||||
*/
|
||||
|
||||
rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE);
|
||||
@@ -253,7 +257,8 @@ parseFromClause(ParseState *pstate, List *frmList, Node **qual)
|
||||
|
||||
foreach(fl, frmList)
|
||||
{
|
||||
Node *n = lfirst(fl);
|
||||
Node *n = lfirst(fl);
|
||||
|
||||
/*
|
||||
* marks this entry to indicate it comes from the FROM clause. In
|
||||
* SQL, the target list can only refer to range variables
|
||||
@@ -266,34 +271,36 @@ parseFromClause(ParseState *pstate, List *frmList, Node **qual)
|
||||
* if we expand * to foo.x.
|
||||
*/
|
||||
if (IsA(n, RangeVar))
|
||||
{
|
||||
transformTableEntry(pstate, (RangeVar *)n);
|
||||
}
|
||||
transformTableEntry(pstate, (RangeVar *) n);
|
||||
else if (IsA(n, JoinExpr))
|
||||
{
|
||||
JoinExpr *j = (JoinExpr *)n;
|
||||
JoinExpr *j = (JoinExpr *) n;
|
||||
|
||||
#ifdef ENABLE_OUTER_JOINS
|
||||
char *lname = transformTableEntry(pstate, (RangeVar *)j->larg);
|
||||
char *lname = transformTableEntry(pstate, (RangeVar *) j->larg);
|
||||
|
||||
#endif
|
||||
char *rname;
|
||||
|
||||
if (IsA((Node *)j->rarg, RangeVar))
|
||||
rname = transformTableEntry(pstate, (RangeVar *)j->rarg);
|
||||
if (IsA((Node *) j->rarg, RangeVar))
|
||||
rname = transformTableEntry(pstate, (RangeVar *) j->rarg);
|
||||
else
|
||||
elog(ERROR, "Nested JOINs are not yet supported");
|
||||
|
||||
#ifdef ENABLE_OUTER_JOINS
|
||||
if (j->jointype == INNER_P)
|
||||
{
|
||||
/* This is an inner join, so rip apart the join node
|
||||
* and transform into a traditional FROM list.
|
||||
* NATURAL JOIN and USING clauses both change the shape
|
||||
* of the result. Need to generate a list of result columns
|
||||
* to use for target list expansion and validation.
|
||||
* Not doing this yet though!
|
||||
|
||||
/*
|
||||
* This is an inner join, so rip apart the join node and
|
||||
* transform into a traditional FROM list. NATURAL JOIN
|
||||
* and USING clauses both change the shape of the result.
|
||||
* Need to generate a list of result columns to use for
|
||||
* target list expansion and validation. Not doing this
|
||||
* yet though!
|
||||
*/
|
||||
if (IsA(j->quals, List))
|
||||
j->quals = lcons(transformUsingClause(pstate, (List *)j->quals, lname, rname), NIL);
|
||||
j->quals = lcons(transformUsingClause(pstate, (List *) j->quals, lname, rname), NIL);
|
||||
|
||||
Assert(qual != NULL);
|
||||
|
||||
@@ -302,19 +309,19 @@ parseFromClause(ParseState *pstate, List *frmList, Node **qual)
|
||||
else
|
||||
elog(ERROR, "Multiple JOIN/ON clauses not handled (internal error)");
|
||||
|
||||
/* if we are transforming this node back into a FROM list,
|
||||
/*
|
||||
* if we are transforming this node back into a FROM list,
|
||||
* then we will need to replace the node with two nodes.
|
||||
* Will need access to the previous list item to change
|
||||
* the link pointer to reference these new nodes.
|
||||
* Try accumulating and returning a new list.
|
||||
* - thomas 1999-01-08
|
||||
* Not doing this yet though!
|
||||
* the link pointer to reference these new nodes. Try
|
||||
* accumulating and returning a new list. - thomas
|
||||
* 1999-01-08 Not doing this yet though!
|
||||
*/
|
||||
|
||||
}
|
||||
else if ((j->jointype == LEFT)
|
||||
|| (j->jointype == RIGHT)
|
||||
|| (j->jointype == FULL))
|
||||
|| (j->jointype == RIGHT)
|
||||
|| (j->jointype == FULL))
|
||||
elog(ERROR, "OUTER JOIN is not implemented");
|
||||
else
|
||||
elog(ERROR, "Unrecognized JOIN clause; tag is %d (internal error)",
|
||||
@@ -545,7 +552,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
|
||||
resdom->restype, false));
|
||||
if (glist == NIL)
|
||||
{
|
||||
int groupref = length(glist) + 1;
|
||||
int groupref = length(glist) + 1;
|
||||
|
||||
restarget->resdom->resgroupref = groupref;
|
||||
grpcl->tleGroupref = groupref;
|
||||
@@ -561,12 +568,12 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
|
||||
GroupClause *gcl = (GroupClause *) lfirst(i);
|
||||
|
||||
if (equal(get_groupclause_expr(gcl, targetlist),
|
||||
restarget->expr))
|
||||
restarget->expr))
|
||||
break;
|
||||
}
|
||||
if (i == NIL) /* not in grouplist already */
|
||||
{
|
||||
int groupref = length(glist) + 1;
|
||||
int groupref = length(glist) + 1;
|
||||
|
||||
restarget->resdom->resgroupref = groupref;
|
||||
grpcl->tleGroupref = groupref;
|
||||
@@ -749,21 +756,22 @@ transformUnionClause(List *unionClause, List *targetlist)
|
||||
/* recursion */
|
||||
qlist = parse_analyze(unionClause, NULL);
|
||||
|
||||
foreach (qlist_item, qlist)
|
||||
foreach(qlist_item, qlist)
|
||||
{
|
||||
Query *query = (Query *) lfirst(qlist_item);
|
||||
List *prev_target = targetlist;
|
||||
List *next_target;
|
||||
int prev_len = 0, next_len = 0;
|
||||
int prev_len = 0,
|
||||
next_len = 0;
|
||||
|
||||
foreach(prev_target, targetlist)
|
||||
if (!((TargetEntry *) lfirst(prev_target))->resdom->resjunk)
|
||||
prev_len++;
|
||||
prev_len++;
|
||||
|
||||
foreach(next_target, query->targetList)
|
||||
if (!((TargetEntry *) lfirst(next_target))->resdom->resjunk)
|
||||
next_len++;
|
||||
|
||||
next_len++;
|
||||
|
||||
if (prev_len != next_len)
|
||||
elog(ERROR, "Each UNION clause must have the same number of columns");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.15 1999/05/22 04:12:26 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.16 1999/05/25 16:10:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -28,7 +28,7 @@
|
||||
Oid DemoteType(Oid inType);
|
||||
Oid PromoteTypeToNext(Oid inType);
|
||||
|
||||
static Oid PreferredType(CATEGORY category, Oid type);
|
||||
static Oid PreferredType(CATEGORY category, Oid type);
|
||||
|
||||
|
||||
/* coerce_type()
|
||||
@@ -36,7 +36,7 @@ static Oid PreferredType(CATEGORY category, Oid type);
|
||||
*/
|
||||
Node *
|
||||
coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
int32 atttypmod)
|
||||
int32 atttypmod)
|
||||
{
|
||||
Node *result = NULL;
|
||||
Oid infunc;
|
||||
@@ -60,6 +60,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
*/
|
||||
else if (inputTypeId != UNKNOWNOID)
|
||||
{
|
||||
|
||||
/*
|
||||
* We already know there is a function which will do this, so
|
||||
* let's use it
|
||||
@@ -77,22 +78,22 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
{
|
||||
Const *con = (Const *) node;
|
||||
|
||||
val = (Datum) textout((struct varlena *)con->constvalue);
|
||||
val = (Datum) textout((struct varlena *) con->constvalue);
|
||||
infunc = typeidInfunc(targetTypeId);
|
||||
con = makeNode(Const);
|
||||
con->consttype = targetTypeId;
|
||||
con->constlen = typeLen(typeidType(targetTypeId));
|
||||
|
||||
/*
|
||||
* Use "-1" for varchar() type.
|
||||
* For char(), we need to pad out the type with the proper
|
||||
* number of spaces. This was a major problem for
|
||||
* DEFAULT string constants to char() types.
|
||||
* Use "-1" for varchar() type. For char(), we need to pad
|
||||
* out the type with the proper number of spaces. This
|
||||
* was a major problem for DEFAULT string constants to
|
||||
* char() types.
|
||||
*/
|
||||
con->constvalue = (Datum) fmgr(infunc,
|
||||
val,
|
||||
typeidTypElem(targetTypeId),
|
||||
(targetTypeId != BPCHAROID) ? -1 : atttypmod);
|
||||
typeidTypElem(targetTypeId),
|
||||
(targetTypeId != BPCHAROID) ? -1 : atttypmod);
|
||||
con->constisnull = false;
|
||||
con->constbyval = typeByVal(typeidType(targetTypeId));
|
||||
con->constisset = false;
|
||||
@@ -150,6 +151,7 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
|
||||
/* don't know what to do for the input type? then quit... */
|
||||
else if (input_typeids[i] == InvalidOid)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* if not unknown input type, try for explicit conversion
|
||||
* using functions...
|
||||
@@ -298,7 +300,7 @@ PreferredType(CATEGORY category, Oid type)
|
||||
case (NETWORK_TYPE):
|
||||
result = INETOID;
|
||||
break;
|
||||
|
||||
|
||||
case (GEOMETRIC_TYPE):
|
||||
case (USER_TYPE):
|
||||
result = type;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.47 1999/05/22 04:12:26 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.48 1999/05/25 16:10:16 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -152,7 +152,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
*/
|
||||
idx = lnext(idx);
|
||||
}
|
||||
result = (Node *) make_array_ref((Node *)param, pno->indirection);
|
||||
result = (Node *) make_array_ref((Node *) param, pno->indirection);
|
||||
}
|
||||
else
|
||||
result = (Node *) param;
|
||||
@@ -251,7 +251,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
{
|
||||
|
||||
/*
|
||||
* look for a column name or a relation name (the default behavior)
|
||||
* look for a column name or a relation name (the default
|
||||
* behavior)
|
||||
*/
|
||||
result = transformIdent(pstate, expr, precedence);
|
||||
break;
|
||||
@@ -343,28 +344,31 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
if (c->arg != NULL)
|
||||
{
|
||||
/* shorthand form was specified, so expand... */
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
A_Expr *a = makeNode(A_Expr);
|
||||
|
||||
a->oper = OP;
|
||||
a->opname = "=";
|
||||
a->lexpr = c->arg;
|
||||
a->rexpr = w->expr;
|
||||
w->expr = (Node *)a;
|
||||
w->expr = (Node *) a;
|
||||
}
|
||||
lfirst(args) = transformExpr(pstate, (Node *) w, precedence);
|
||||
}
|
||||
|
||||
/* It's not shorthand anymore, so drop the implicit argument.
|
||||
* This is necessary to keep the executor from seeing an
|
||||
* untransformed expression...
|
||||
/*
|
||||
* It's not shorthand anymore, so drop the implicit
|
||||
* argument. This is necessary to keep the executor from
|
||||
* seeing an untransformed expression...
|
||||
*/
|
||||
c->arg = NULL;
|
||||
|
||||
/* transform the default clause */
|
||||
if (c->defresult == NULL)
|
||||
{
|
||||
A_Const *n = makeNode(A_Const);
|
||||
A_Const *n = makeNode(A_Const);
|
||||
|
||||
n->val.type = T_Null;
|
||||
c->defresult = (Node *)n;
|
||||
c->defresult = (Node *) n;
|
||||
}
|
||||
c->defresult = transformExpr(pstate, (Node *) c->defresult, precedence);
|
||||
|
||||
@@ -380,7 +384,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
wtype = exprType(w->result);
|
||||
/* move on to next one if no new information... */
|
||||
if (wtype && (wtype != UNKNOWNOID)
|
||||
&& (wtype != ptype))
|
||||
&& (wtype != ptype))
|
||||
{
|
||||
/* so far, only nulls so take anything... */
|
||||
if (!ptype)
|
||||
@@ -388,15 +392,23 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
ptype = wtype;
|
||||
pcategory = TypeCategory(ptype);
|
||||
}
|
||||
/* both types in different categories? then not much hope... */
|
||||
|
||||
/*
|
||||
* both types in different categories? then not
|
||||
* much hope...
|
||||
*/
|
||||
else if ((TypeCategory(wtype) != pcategory)
|
||||
|| ((TypeCategory(wtype) == USER_TYPE)
|
||||
&& (TypeCategory(c->casetype) == USER_TYPE)))
|
||||
|| ((TypeCategory(wtype) == USER_TYPE)
|
||||
&& (TypeCategory(c->casetype) == USER_TYPE)))
|
||||
{
|
||||
elog(ERROR,"CASE/WHEN types '%s' and '%s' not matched",
|
||||
elog(ERROR, "CASE/WHEN types '%s' and '%s' not matched",
|
||||
typeidTypeName(c->casetype), typeidTypeName(wtype));
|
||||
}
|
||||
/* new one is preferred and can convert? then take it... */
|
||||
|
||||
/*
|
||||
* new one is preferred and can convert? then take
|
||||
* it...
|
||||
*/
|
||||
else if (IsPreferredType(pcategory, wtype)
|
||||
&& can_coerce_type(1, &ptype, &wtype))
|
||||
{
|
||||
@@ -409,21 +421,24 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
/* Convert default result clause, if necessary */
|
||||
if (c->casetype != ptype)
|
||||
{
|
||||
if (! c->casetype)
|
||||
if (!c->casetype)
|
||||
{
|
||||
/* default clause is NULL,
|
||||
* so assign preferred type from WHEN clauses... */
|
||||
|
||||
/*
|
||||
* default clause is NULL, so assign preferred
|
||||
* type from WHEN clauses...
|
||||
*/
|
||||
c->casetype = ptype;
|
||||
}
|
||||
else if (can_coerce_type(1, &c->casetype, &ptype))
|
||||
{
|
||||
c->defresult = coerce_type(pstate, c->defresult,
|
||||
c->casetype, ptype, -1);
|
||||
c->casetype, ptype, -1);
|
||||
c->casetype = ptype;
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR,"CASE/ELSE unable to convert to type %s",
|
||||
elog(ERROR, "CASE/ELSE unable to convert to type %s",
|
||||
typeidTypeName(ptype));
|
||||
}
|
||||
}
|
||||
@@ -431,11 +446,15 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
/* Convert when clauses, if not null and if necessary */
|
||||
foreach(args, c->args)
|
||||
{
|
||||
Oid wtype;
|
||||
Oid wtype;
|
||||
|
||||
w = lfirst(args);
|
||||
wtype = exprType(w->result);
|
||||
/* only bother with conversion if not NULL and different type... */
|
||||
|
||||
/*
|
||||
* only bother with conversion if not NULL and
|
||||
* different type...
|
||||
*/
|
||||
if (wtype && (wtype != ptype))
|
||||
{
|
||||
if (can_coerce_type(1, &wtype, &ptype))
|
||||
@@ -445,7 +464,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR,"CASE/WHEN unable to convert to type %s",
|
||||
elog(ERROR, "CASE/WHEN unable to convert to type %s",
|
||||
typeidTypeName(ptype));
|
||||
}
|
||||
}
|
||||
@@ -461,14 +480,18 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
|
||||
w->expr = transformExpr(pstate, (Node *) w->expr, precedence);
|
||||
if (exprType(w->expr) != BOOLOID)
|
||||
elog(ERROR,"WHEN clause must have a boolean result");
|
||||
elog(ERROR, "WHEN clause must have a boolean result");
|
||||
|
||||
/* result is NULL for NULLIF() construct - thomas 1998-11-11 */
|
||||
/*
|
||||
* result is NULL for NULLIF() construct - thomas
|
||||
* 1998-11-11
|
||||
*/
|
||||
if (w->result == NULL)
|
||||
{
|
||||
A_Const *n = makeNode(A_Const);
|
||||
A_Const *n = makeNode(A_Const);
|
||||
|
||||
n->val.type = T_Null;
|
||||
w->result = (Node *)n;
|
||||
w->result = (Node *) n;
|
||||
}
|
||||
w->result = transformExpr(pstate, (Node *) w->result, precedence);
|
||||
result = expr;
|
||||
@@ -530,7 +553,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence)
|
||||
att->relname = rte->refname;
|
||||
att->attrs = lcons(makeString(ident->name), NIL);
|
||||
column_result = (Node *) ParseNestedFuncOrColumn(pstate, att,
|
||||
&pstate->p_last_resno, precedence);
|
||||
&pstate->p_last_resno, precedence);
|
||||
}
|
||||
|
||||
/* try to find the ident as a relation */
|
||||
@@ -602,11 +625,13 @@ exprType(Node *expr)
|
||||
break;
|
||||
case T_SubLink:
|
||||
{
|
||||
SubLink *sublink = (SubLink *) expr;
|
||||
SubLink *sublink = (SubLink *) expr;
|
||||
|
||||
if (sublink->subLinkType == EXPR_SUBLINK)
|
||||
{
|
||||
/* return the result type of the combining operator */
|
||||
Expr *op_expr = (Expr *) lfirst(sublink->oper);
|
||||
Expr *op_expr = (Expr *) lfirst(sublink->oper);
|
||||
|
||||
type = op_expr->typeOid;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.45 1999/05/22 04:12:27 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.46 1999/05/25 16:10:17 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -77,9 +77,9 @@ static int match_argtypes(int nargs,
|
||||
static List *setup_tlist(char *attname, Oid relid);
|
||||
static List *setup_base_tlist(Oid typeid);
|
||||
static Oid *func_select_candidate(int nargs, Oid *input_typeids,
|
||||
CandidateList candidates);
|
||||
static int agg_get_candidates(char *aggname, Oid typeId, CandidateList *candidates);
|
||||
static Oid agg_select_candidate(Oid typeid, CandidateList candidates);
|
||||
CandidateList candidates);
|
||||
static int agg_get_candidates(char *aggname, Oid typeId, CandidateList *candidates);
|
||||
static Oid agg_select_candidate(Oid typeid, CandidateList candidates);
|
||||
|
||||
#define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false)
|
||||
|
||||
@@ -91,7 +91,7 @@ typedef struct _SuperQE
|
||||
} SuperQE;
|
||||
|
||||
/*
|
||||
** ParseNestedFuncOrColumn
|
||||
** ParseNestedFuncOrColumn
|
||||
** Given a nested dot expression (i.e. (relation func ... attr), build up
|
||||
** a tree with of Iter and Func nodes.
|
||||
*/
|
||||
@@ -139,12 +139,12 @@ agg_get_candidates(char *aggname,
|
||||
Oid typeId,
|
||||
CandidateList *candidates)
|
||||
{
|
||||
CandidateList current_candidate;
|
||||
Relation pg_aggregate_desc;
|
||||
HeapScanDesc pg_aggregate_scan;
|
||||
HeapTuple tup;
|
||||
Form_pg_aggregate agg;
|
||||
int ncandidates = 0;
|
||||
CandidateList current_candidate;
|
||||
Relation pg_aggregate_desc;
|
||||
HeapScanDesc pg_aggregate_scan;
|
||||
HeapTuple tup;
|
||||
Form_pg_aggregate agg;
|
||||
int ncandidates = 0;
|
||||
|
||||
static ScanKeyData aggKey[1] = {
|
||||
{0, Anum_pg_aggregate_aggname, F_NAMEEQ}};
|
||||
@@ -157,7 +157,7 @@ agg_get_candidates(char *aggname,
|
||||
pg_aggregate_desc = heap_openr(AggregateRelationName);
|
||||
pg_aggregate_scan = heap_beginscan(pg_aggregate_desc,
|
||||
0,
|
||||
SnapshotSelf, /* ??? */
|
||||
SnapshotSelf, /* ??? */
|
||||
1,
|
||||
aggKey);
|
||||
|
||||
@@ -185,12 +185,12 @@ agg_get_candidates(char *aggname,
|
||||
static Oid
|
||||
agg_select_candidate(Oid typeid, CandidateList candidates)
|
||||
{
|
||||
CandidateList current_candidate;
|
||||
CandidateList last_candidate;
|
||||
Oid current_typeid;
|
||||
int ncandidates;
|
||||
CATEGORY category,
|
||||
current_category;
|
||||
CandidateList current_candidate;
|
||||
CandidateList last_candidate;
|
||||
Oid current_typeid;
|
||||
int ncandidates;
|
||||
CATEGORY category,
|
||||
current_category;
|
||||
|
||||
/*
|
||||
* Look for candidates which allow coersion and have a preferred type.
|
||||
@@ -227,13 +227,11 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
|
||||
}
|
||||
/* otherwise, don't bother keeping this one around... */
|
||||
else if (last_candidate != NULL)
|
||||
{
|
||||
last_candidate->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ((ncandidates == 1) ? candidates->args[0] : 0);
|
||||
} /* agg_select_candidate() */
|
||||
} /* agg_select_candidate() */
|
||||
|
||||
|
||||
/*
|
||||
@@ -352,13 +350,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* Parsing aggregates.
|
||||
*/
|
||||
Type tp;
|
||||
Oid basetype;
|
||||
int ncandidates;
|
||||
CandidateList candidates;
|
||||
Type tp;
|
||||
Oid basetype;
|
||||
int ncandidates;
|
||||
CandidateList candidates;
|
||||
|
||||
/*
|
||||
* the aggregate COUNT is a special case, ignore its base
|
||||
@@ -378,14 +377,13 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
fargs, precedence);
|
||||
|
||||
/*
|
||||
* No exact match yet, so see if there is another entry
|
||||
* in the aggregate table which is compatible.
|
||||
* - thomas 1998-12-05
|
||||
* No exact match yet, so see if there is another entry in the
|
||||
* aggregate table which is compatible. - thomas 1998-12-05
|
||||
*/
|
||||
ncandidates = agg_get_candidates(funcname, basetype, &candidates);
|
||||
if (ncandidates > 0)
|
||||
{
|
||||
Oid type;
|
||||
Oid type;
|
||||
|
||||
type = agg_select_candidate(basetype, candidates);
|
||||
if (OidIsValid(type))
|
||||
@@ -399,7 +397,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR,"Unable to select an aggregate function %s(%s)",
|
||||
elog(ERROR, "Unable to select an aggregate function %s(%s)",
|
||||
funcname, typeidTypeName(basetype));
|
||||
}
|
||||
}
|
||||
@@ -407,18 +405,16 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
/*
|
||||
* See if this is a single argument function with the function
|
||||
* name also a type name and the input argument and type name
|
||||
* binary compatible...
|
||||
* This means that you are trying for a type conversion which does not
|
||||
* need to take place, so we'll just pass through the argument itself.
|
||||
* (make this clearer with some extra brackets - thomas 1998-12-05)
|
||||
* binary compatible... This means that you are trying for a
|
||||
* type conversion which does not need to take place, so we'll
|
||||
* just pass through the argument itself. (make this clearer
|
||||
* with some extra brackets - thomas 1998-12-05)
|
||||
*/
|
||||
if ((HeapTupleIsValid(tp = SearchSysCacheTuple(TYPNAME,
|
||||
PointerGetDatum(funcname),
|
||||
PointerGetDatum(funcname),
|
||||
0, 0, 0)))
|
||||
&& IS_BINARY_COMPATIBLE(typeTypeId(tp), basetype))
|
||||
{
|
||||
return ((Node *) lfirst(fargs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,6 +436,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
|
||||
if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
|
||||
{
|
||||
|
||||
/*
|
||||
* a relation
|
||||
*/
|
||||
@@ -551,9 +548,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
if (attisset)
|
||||
{
|
||||
if (!strcmp(funcname, "*"))
|
||||
{
|
||||
funcnode->func_tlist = expandAll(pstate, relname, refname, curr_resno);
|
||||
}
|
||||
else
|
||||
{
|
||||
funcnode->func_tlist = setup_tlist(funcname, argrelid);
|
||||
@@ -581,13 +576,13 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
||||
seqrel = textout((text *) DatumGetPointer(seq->constvalue));
|
||||
/* Do we have nextval('"Aa"')? */
|
||||
if (strlen(seqrel) >= 2 &&
|
||||
seqrel[0] == '\"' && seqrel[strlen(seqrel)-1] == '\"')
|
||||
seqrel[0] == '\"' && seqrel[strlen(seqrel) - 1] == '\"')
|
||||
{
|
||||
/* strip off quotes, keep case */
|
||||
seqrel = pstrdup(seqrel+1);
|
||||
seqrel[strlen(seqrel)-1] = '\0';
|
||||
seqrel = pstrdup(seqrel + 1);
|
||||
seqrel[strlen(seqrel) - 1] = '\0';
|
||||
pfree(DatumGetPointer(seq->constvalue));
|
||||
seq->constvalue = (Datum)textin(seqrel);
|
||||
seq->constvalue = (Datum) textin(seqrel);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -669,7 +664,7 @@ func_get_candidates(char *funcname, int nargs)
|
||||
Relation heapRelation;
|
||||
Relation idesc;
|
||||
ScanKeyData skey;
|
||||
HeapTupleData tuple;
|
||||
HeapTupleData tuple;
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
Form_pg_proc pgProcP;
|
||||
@@ -837,9 +832,7 @@ func_select_candidate(int nargs,
|
||||
ncandidates++;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_candidate->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ncandidates == 1)
|
||||
@@ -870,9 +863,7 @@ func_select_candidate(int nargs,
|
||||
}
|
||||
else if ((current_category != slot_category)
|
||||
&& IS_BUILTIN_TYPE(current_type))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (current_type != slot_type)
|
||||
{
|
||||
if (IsPreferredType(slot_category, current_type))
|
||||
@@ -881,16 +872,12 @@ func_select_candidate(int nargs,
|
||||
candidates = current_candidate;
|
||||
}
|
||||
else if (IsPreferredType(slot_category, slot_type))
|
||||
{
|
||||
candidates->next = current_candidate->next;
|
||||
}
|
||||
candidates->next = current_candidate->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot_type != InvalidOid)
|
||||
{
|
||||
input_typeids[i] = slot_type;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -979,7 +966,7 @@ func_get_detail(char *funcname,
|
||||
ftup = SearchSysCacheTuple(PRONAME,
|
||||
PointerGetDatum(funcname),
|
||||
Int32GetDatum(nargs),
|
||||
PointerGetDatum(*true_typeids),
|
||||
PointerGetDatum(*true_typeids),
|
||||
0);
|
||||
Assert(HeapTupleIsValid(ftup));
|
||||
}
|
||||
@@ -991,8 +978,8 @@ func_get_detail(char *funcname,
|
||||
else if (ncandidates > 1)
|
||||
{
|
||||
*true_typeids = func_select_candidate(nargs,
|
||||
current_input_typeids,
|
||||
current_function_typeids);
|
||||
current_input_typeids,
|
||||
current_function_typeids);
|
||||
|
||||
/* couldn't decide, so quit */
|
||||
if (*true_typeids == NULL)
|
||||
@@ -1006,9 +993,9 @@ func_get_detail(char *funcname,
|
||||
else
|
||||
{
|
||||
ftup = SearchSysCacheTuple(PRONAME,
|
||||
PointerGetDatum(funcname),
|
||||
PointerGetDatum(funcname),
|
||||
Int32GetDatum(nargs),
|
||||
PointerGetDatum(*true_typeids),
|
||||
PointerGetDatum(*true_typeids),
|
||||
0);
|
||||
Assert(HeapTupleIsValid(ftup));
|
||||
}
|
||||
@@ -1304,9 +1291,9 @@ make_arguments(ParseState *pstate,
|
||||
if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
|
||||
{
|
||||
lfirst(current_fargs) = parser_typecast2(lfirst(current_fargs),
|
||||
input_typeids[i],
|
||||
typeidType(function_typeids[i]),
|
||||
-1);
|
||||
input_typeids[i],
|
||||
typeidType(function_typeids[i]),
|
||||
-1);
|
||||
}
|
||||
|
||||
/* types don't match? then force coersion using a function call... */
|
||||
@@ -1321,7 +1308,7 @@ make_arguments(ParseState *pstate,
|
||||
}
|
||||
|
||||
/*
|
||||
** setup_tlist
|
||||
** setup_tlist
|
||||
** Build a tlist that says which attribute to project to.
|
||||
** 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,
|
||||
@@ -1359,7 +1346,7 @@ setup_tlist(char *attname, Oid relid)
|
||||
}
|
||||
|
||||
/*
|
||||
** setup_base_tlist
|
||||
** setup_base_tlist
|
||||
** Build a tlist that extracts a base type from the tuple
|
||||
** returned by the executor.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.24 1999/05/10 00:45:29 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.25 1999/05/25 16:10:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -27,8 +27,8 @@
|
||||
#include "storage/bufmgr.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
static Oid * oper_select_candidate(int nargs, Oid *input_typeids,
|
||||
CandidateList candidates);
|
||||
static Oid *oper_select_candidate(int nargs, Oid *input_typeids,
|
||||
CandidateList candidates);
|
||||
static int binary_oper_get_candidates(char *opname,
|
||||
Oid leftTypeId,
|
||||
Oid rightTypeId,
|
||||
@@ -227,9 +227,7 @@ oper_select_candidate(int nargs,
|
||||
}
|
||||
/* otherwise, don't bother keeping this one... */
|
||||
else
|
||||
{
|
||||
last_candidate->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ncandidates <= 1)
|
||||
@@ -281,18 +279,14 @@ oper_select_candidate(int nargs,
|
||||
ncandidates++;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_candidate->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ncandidates <= 1)
|
||||
{
|
||||
if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0])
|
||||
|| ((nargs > 1) && !can_coerce_type(1, &input_typeids[1], &candidates->args[1])))
|
||||
{
|
||||
|| ((nargs > 1) && !can_coerce_type(1, &input_typeids[1], &candidates->args[1])))
|
||||
ncandidates = 0;
|
||||
}
|
||||
return (ncandidates == 1) ? candidates->args : NULL;
|
||||
}
|
||||
|
||||
@@ -349,9 +343,7 @@ oper_select_candidate(int nargs,
|
||||
slot_type = current_type;
|
||||
}
|
||||
else if (current_category != slot_category)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (current_type != slot_type)
|
||||
{
|
||||
if (IsPreferredType(slot_category, current_type))
|
||||
@@ -366,9 +358,7 @@ oper_select_candidate(int nargs,
|
||||
}
|
||||
|
||||
if (slot_type != InvalidOid)
|
||||
{
|
||||
input_typeids[i] = slot_type;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -656,9 +646,7 @@ right_oper(char *op, Oid arg)
|
||||
CharGetDatum('r'));
|
||||
}
|
||||
else
|
||||
{
|
||||
tup = NULL;
|
||||
}
|
||||
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
@@ -717,9 +705,7 @@ left_oper(char *op, Oid arg)
|
||||
CharGetDatum('l'));
|
||||
}
|
||||
else
|
||||
{
|
||||
tup = NULL;
|
||||
}
|
||||
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.21 1999/05/22 04:12:28 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.22 1999/05/25 16:10:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -446,8 +446,8 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
|
||||
if (can_coerce_type(1, &attrtype_id, &attrtype_target))
|
||||
{
|
||||
Node *expr = coerce_type(pstate, expr, attrtype_id,
|
||||
attrtype_target,
|
||||
get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target));
|
||||
attrtype_target,
|
||||
get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target));
|
||||
|
||||
elog(ERROR, "Type %s(%d) can be coerced to match target column %s(%d)",
|
||||
colname, get_atttypmod(rte->relid, resdomno_id),
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.39 1999/05/23 21:42:09 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.40 1999/05/25 16:10:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -64,10 +64,12 @@ MakeTargetEntryIdent(ParseState *pstate,
|
||||
|
||||
if (pstate->p_is_insert && !resjunk)
|
||||
{
|
||||
/* Assign column name of destination column to the new TLE.
|
||||
* XXX this is probably WRONG in INSERT ... SELECT case,
|
||||
* since handling of GROUP BY and so forth probably should use
|
||||
* the source table's names not the destination's names.
|
||||
|
||||
/*
|
||||
* Assign column name of destination column to the new TLE. XXX
|
||||
* this is probably WRONG in INSERT ... SELECT case, since
|
||||
* handling of GROUP BY and so forth probably should use the
|
||||
* source table's names not the destination's names.
|
||||
*/
|
||||
if (pstate->p_insert_columns != NIL)
|
||||
{
|
||||
@@ -123,8 +125,8 @@ MakeTargetEntryIdent(ParseState *pstate,
|
||||
if (can_coerce_type(1, &attrtype_id, &attrtype_target))
|
||||
{
|
||||
expr = coerce_type(pstate, node, attrtype_id,
|
||||
attrtype_target,
|
||||
get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target));
|
||||
attrtype_target,
|
||||
get_atttypmod(pstate->p_target_relation->rd_id, resdomno_target));
|
||||
expr = transformExpr(pstate, expr, EXPR_COLUMN_FIRST);
|
||||
tent = MakeTargetEntryExpr(pstate, *resname, expr, false, false);
|
||||
expr = tent->expr;
|
||||
@@ -248,7 +250,7 @@ MakeTargetEntryExpr(ParseState *pstate,
|
||||
if (!HeapTupleIsValid(expr))
|
||||
elog(ERROR, "Attribute '%s' is of type '%s'"
|
||||
" but expression is of type '%s'"
|
||||
"\n\tYou will need to rewrite or cast the expression",
|
||||
"\n\tYou will need to rewrite or cast the expression",
|
||||
colname,
|
||||
typeidTypeName(attrtype),
|
||||
typeidTypeName(type_id));
|
||||
@@ -326,20 +328,20 @@ static TargetEntry *
|
||||
MakeTargetEntryCase(ParseState *pstate,
|
||||
ResTarget *res)
|
||||
{
|
||||
TargetEntry *tent;
|
||||
CaseExpr *expr;
|
||||
Resdom *resnode;
|
||||
int resdomno;
|
||||
Oid type_id;
|
||||
int32 type_mod;
|
||||
TargetEntry *tent;
|
||||
CaseExpr *expr;
|
||||
Resdom *resnode;
|
||||
int resdomno;
|
||||
Oid type_id;
|
||||
int32 type_mod;
|
||||
|
||||
expr = (CaseExpr *)transformExpr(pstate, (Node *)res->val, EXPR_COLUMN_FIRST);
|
||||
expr = (CaseExpr *) transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
|
||||
|
||||
type_id = expr->casetype;
|
||||
type_mod = -1;
|
||||
handleTargetColname(pstate, &res->name, NULL, NULL);
|
||||
if (res->name == NULL)
|
||||
res->name = FigureColname((Node *)expr, res->val);
|
||||
res->name = FigureColname((Node *) expr, res->val);
|
||||
|
||||
resdomno = pstate->p_last_resno++;
|
||||
resnode = makeResdom((AttrNumber) resdomno,
|
||||
@@ -352,7 +354,7 @@ MakeTargetEntryCase(ParseState *pstate,
|
||||
|
||||
tent = makeNode(TargetEntry);
|
||||
tent->resdom = resnode;
|
||||
tent->expr = (Node *)expr;
|
||||
tent->expr = (Node *) expr;
|
||||
|
||||
return tent;
|
||||
} /* MakeTargetEntryCase() */
|
||||
@@ -435,7 +437,7 @@ MakeTargetEntryComplex(ParseState *pstate,
|
||||
else
|
||||
{
|
||||
/* this is not an array assignment */
|
||||
char *colname = res->name;
|
||||
char *colname = res->name;
|
||||
|
||||
if (colname == NULL)
|
||||
{
|
||||
@@ -564,7 +566,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
|
||||
|
||||
identname = ((Ident *) res->val)->name;
|
||||
tent = MakeTargetEntryIdent(pstate,
|
||||
(Node *) res->val, &res->name, NULL, identname, false);
|
||||
(Node *) res->val, &res->name, NULL, identname, false);
|
||||
break;
|
||||
}
|
||||
case T_ParamNo:
|
||||
@@ -619,7 +621,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
|
||||
att->relname, &pstate->p_last_resno);
|
||||
else
|
||||
lnext(tail_p_target) = expandAll(pstate, att->relname, att->relname,
|
||||
&pstate->p_last_resno);
|
||||
&pstate->p_last_resno);
|
||||
expand_star = true;
|
||||
}
|
||||
}
|
||||
@@ -668,9 +670,7 @@ CoerceTargetExpr(ParseState *pstate,
|
||||
Oid attrtype)
|
||||
{
|
||||
if (can_coerce_type(1, &type_id, &attrtype))
|
||||
{
|
||||
expr = coerce_type(pstate, expr, type_id, attrtype, -1);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_STRING_HACKS
|
||||
|
||||
@@ -818,6 +818,7 @@ ExpandAllTables(ParseState *pstate)
|
||||
rtable = pstate->p_rtable;
|
||||
if (pstate->p_is_rule)
|
||||
{
|
||||
|
||||
/*
|
||||
* skip first two entries, "*new*" and "*current*"
|
||||
*/
|
||||
@@ -876,7 +877,7 @@ FigureColname(Node *expr, Node *resval)
|
||||
{
|
||||
switch (nodeTag(expr))
|
||||
{
|
||||
case T_Aggref:
|
||||
case T_Aggref:
|
||||
return (char *) ((Aggref *) expr)->aggname;
|
||||
case T_Expr:
|
||||
if (((Expr *) expr)->opType == FUNC_EXPR)
|
||||
@@ -887,7 +888,8 @@ FigureColname(Node *expr, Node *resval)
|
||||
break;
|
||||
case T_CaseExpr:
|
||||
{
|
||||
char *name;
|
||||
char *name;
|
||||
|
||||
name = FigureColname(((CaseExpr *) expr)->defresult, resval);
|
||||
if (!strcmp(name, "?column?"))
|
||||
name = "case";
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.20 1999/05/10 00:45:29 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.21 1999/05/25 16:10:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -172,6 +172,7 @@ typeidOutfunc(Oid type_id)
|
||||
outfunc = type->typoutput;
|
||||
return outfunc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Oid
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.38 1999/05/13 07:28:39 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.39 1999/05/25 16:10:24 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#if defined(FLEX_SCANNER)
|
||||
extern void DeleteBuffer(void);
|
||||
|
||||
#endif /* FLEX_SCANNER */
|
||||
|
||||
char *parseString; /* the char* which holds the string to be
|
||||
@@ -31,6 +32,7 @@ List *parsetree; /* result of parsing is left here */
|
||||
#ifdef SETS_FIXED
|
||||
static void fixupsets();
|
||||
static void define_sets();
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/scansup.c,v 1.12 1999/02/13 23:17:12 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/scansup.c,v 1.13 1999/05/25 16:10:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -51,8 +51,10 @@ scanstr(char *s)
|
||||
{
|
||||
if (s[i] == '\'')
|
||||
{
|
||||
/* Note: if scanner is working right, unescaped quotes can only
|
||||
* appear in pairs, so there should be another character.
|
||||
|
||||
/*
|
||||
* Note: if scanner is working right, unescaped quotes can
|
||||
* only appear in pairs, so there should be another character.
|
||||
*/
|
||||
i++;
|
||||
newStr[j] = s[i];
|
||||
|
||||
Reference in New Issue
Block a user