Commit 03d5c070 authored by Thomas G. Lockhart's avatar Thomas G. Lockhart

Modify the outer join placeholder code with something closer to working

 code. Works here, but not completely implemented past this point.
parent 8f0a76f0
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.56 1999/02/21 03:49:00 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.57 1999/02/23 07:42:41 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -107,7 +107,7 @@ Oid param_type(int t); /* used in parse_expr.c */
DefElem *defelt;
ParamString *param;
SortGroupBy *sortgroupby;
JoinUsing *joinusing;
JoinExpr *joinexpr;
IndexElem *ielem;
RangeVar *range;
RelExpr *relexp;
......@@ -131,7 +131,7 @@ Oid param_type(int t); /* used in parse_expr.c */
RemoveFuncStmt, RemoveStmt,
RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
UpdateStmt, InsertStmt, select_w_o_sort, SelectStmt, NotifyStmt, DeleteStmt,
UpdateStmt, InsertStmt, select_clause, SelectStmt, NotifyStmt, DeleteStmt,
ClusterStmt, ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
CreateUserStmt, AlterUserStmt, DropUserStmt, RuleActionStmt
......@@ -144,7 +144,6 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <str> user_valid_clause
%type <list> user_group_list, user_group_clause
%type <str> join_expr, join_outer, join_spec
%type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
%type <str> TriggerEvents, TriggerFuncArg
......@@ -167,7 +166,7 @@ Oid param_type(int t); /* used in parse_expr.c */
oper_argtypes, RuleActionList, RuleActionBlock, RuleActionMulti,
opt_column_list, columnList, opt_va_list, va_list,
sort_clause, sortby_list, index_params, index_list, name_list,
from_clause, from_list, opt_array_bounds, nest_array_bounds,
from_clause, from_expr, table_list, opt_array_bounds, nest_array_bounds,
expr_list, attrs, res_target_list, res_target_list2,
def_list, opt_indirection, group_clause, TriggerFuncArgs,
opt_select_limit
......@@ -177,14 +176,16 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <boolean> TriggerForOpt, TriggerForType, OptTemp
%type <list> for_update_clause
%type <list> join_list
%type <joinusing>
join_using
%type <list> for_update_clause, update_list
%type <boolean> opt_union
%type <boolean> opt_table
%type <boolean> opt_trans
%type <list> join_clause_with_union, join_clause, join_list, join_qual, using_list
%type <node> join_expr, using_expr
%type <str> join_outer
%type <ival> join_type
%type <node> position_expr
%type <list> extract_list, position_list
%type <list> substr_list, substr_from, substr_for, trim_list
......@@ -226,7 +227,7 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <attr> event_object, attr
%type <sortgroupby> sortby
%type <ielem> index_elem, func_index
%type <range> from_val
%type <range> table_expr
%type <relexp> relation_expr
%type <target> res_target_el, res_target_el2
%type <paramno> ParamNo
......@@ -858,20 +859,15 @@ ColConstraint:
{ $$ = $1; }
;
/* The column constraint WITH NULL gives a shift/reduce error
* because it requires yacc to look more than one token ahead to
* resolve WITH TIME ZONE and WITH NULL.
* So, leave it out of the syntax for now.
| WITH NULL_P
{
$$ = NULL;
}
* - thomas 1998-09-12
*
* DEFAULT NULL is already the default for Postgres.
/* DEFAULT NULL is already the default for Postgres.
* Bue define it here and carry it forward into the system
* to make it explicit.
* - thomas 1998-09-13
* WITH NULL and NULL are not SQL92-standard syntax elements,
* so leave them out. Use DEFAULT NULL to explicitly indicate
* that a column may have that value. WITH NULL leads to
* shift/reduce conflicts with WITH TIME ZONE anyway.
* - thomas 1999-01-08
*/
ColConstraintElem: CHECK '(' constraint_expr ')'
{
......@@ -2735,8 +2731,10 @@ opt_of: OF columnList
* accepts the use of '(' and ')' to select an order of set operations.
*
* The rule returns a SelectStmt Node having the set operations attached to
* unionClause and intersectClause (NIL if no set operations were present) */
SelectStmt: select_w_o_sort sort_clause for_update_clause opt_select_limit
* unionClause and intersectClause (NIL if no set operations were present)
*/
SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
{
/* There were no set operations, so just attach the sortClause */
if IsA($1, SelectStmt)
......@@ -2827,7 +2825,7 @@ SelectStmt: select_w_o_sort sort_clause for_update_clause opt_select_limit
* the A_Expr Nodes.
* If no set operations show up in the query the tree consists only of one
* SelectStmt Node */
select_w_o_sort: '(' select_w_o_sort ')'
select_clause: '(' select_clause ')'
{
$$ = $2;
}
......@@ -2835,12 +2833,12 @@ select_w_o_sort: '(' select_w_o_sort ')'
{
$$ = $1;
}
| select_w_o_sort EXCEPT select_w_o_sort
| select_clause EXCEPT select_clause
{
$$ = (Node *)makeA_Expr(AND,NULL,$1,
makeA_Expr(NOT,NULL,NULL,$3));
}
| select_w_o_sort UNION opt_union select_w_o_sort
| select_clause UNION opt_union select_clause
{
if (IsA($4, SelectStmt))
{
......@@ -2849,7 +2847,7 @@ select_w_o_sort: '(' select_w_o_sort ')'
}
$$ = (Node *)makeA_Expr(OR,NULL,$1,$4);
}
| select_w_o_sort INTERSECT select_w_o_sort
| select_clause INTERSECT select_clause
{
$$ = (Node *)makeA_Expr(AND,NULL,$1,$3);
}
......@@ -3024,7 +3022,7 @@ name_list: name
{ $$ = lappend($1,makeString($3)); }
;
group_clause: GROUP BY expr_list { $$ = $3; }
group_clause: GROUP BY expr_list { $$ = $3; }
| /*EMPTY*/ { $$ = NIL; }
;
......@@ -3035,19 +3033,12 @@ having_clause: HAVING a_expr
| /*EMPTY*/ { $$ = NULL; }
;
for_update_clause:
FOR UPDATE
{
$$ = lcons(NULL, NULL);
}
| FOR UPDATE OF va_list
{
$$ = $4;
}
| /* EMPTY */
{
$$ = NULL;
}
for_update_clause: FOR UPDATE update_list { $$ = $3; }
| /* EMPTY */ { $$ = NULL; }
;
update_list: OF va_list { $$ = $2; }
| /* EMPTY */ { $$ = lcons(NULL, NULL); }
;
/*****************************************************************************
......@@ -3058,24 +3049,25 @@ for_update_clause:
*
*****************************************************************************/
from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
{
$$ = NIL;
elog(ERROR,"JOIN not yet implemented");
}
| FROM from_list { $$ = $2; }
from_clause: FROM from_expr { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
from_list: from_list ',' from_val
from_expr: '(' join_clause_with_union ')'
{ $$ = $2; }
| join_clause
{ $$ = $1; }
| table_list
{ $$ = $1; }
;
table_list: table_list ',' table_expr
{ $$ = lappend($1, $3); }
| from_val CROSS JOIN from_val
{ elog(ERROR,"CROSS JOIN not yet implemented"); }
| from_val
| table_expr
{ $$ = lcons($1, NIL); }
;
from_val: relation_expr AS ColLabel
table_expr: relation_expr AS ColLabel
{
$$ = makeNode(RangeVar);
$$->relExpr = $1;
......@@ -3095,64 +3087,130 @@ from_val: relation_expr AS ColLabel
}
;
join_expr: NATURAL join_expr { $$ = NULL; }
| FULL join_outer
{ elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
/* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
* all result rows which would have matched on an INNER JOIN.
* Let's reject this for now. - thomas 1999-01-08
*/
join_clause_with_union: join_clause
{ $$ = $1; }
| table_expr UNION JOIN table_expr
{ elog(ERROR,"UNION JOIN not yet implemented"); }
;
join_clause: table_expr join_list
{
Node *n = lfirst($2);
/* JoinExpr came back? then it is a join of some sort...
*/
if (IsA(n, JoinExpr))
{
JoinExpr *j = (JoinExpr *)n;
j->larg = $1;
$$ = $2;
}
/* otherwise, it was a cross join,
* which we just represent as an inner join...
*/
else
$$ = lcons($1, $2);
}
;
join_list: join_list join_expr
{
$$ = lappend($1, $2);
}
| join_expr
{
$$ = lcons($1, NIL);
}
;
/* This is everything but the left side of a join.
* Note that a CROSS JOIN is the same as an unqualified
* inner join, so just pass back the right-side table.
* A NATURAL JOIN implicitly matches column names between
* tables, so we'll collect those during the later transformation.
*/
join_expr: join_type JOIN table_expr join_qual
{
JoinExpr *n = makeNode(JoinExpr);
n->jointype = $1;
n->rarg = (Node *)$3;
n->quals = $4;
$$ = (Node *)n;
}
| NATURAL join_type JOIN table_expr
{
JoinExpr *n = makeNode(JoinExpr);
n->jointype = $2;
n->rarg = (Node *)$4;
n->quals = NULL; /* figure out which columns later... */
$$ = (Node *)n;
}
| CROSS JOIN table_expr
{ $$ = (Node *)$3; }
;
/* OUTER is just noise... */
join_type: FULL join_outer
{
$$ = FULL;
elog(NOTICE,"FULL OUTER JOIN not yet implemented");
}
| LEFT join_outer
{ elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
{
$$ = LEFT;
elog(NOTICE,"LEFT OUTER JOIN not yet implemented");
}
| RIGHT join_outer
{ elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
{
$$ = RIGHT;
elog(NOTICE,"RIGHT OUTER JOIN not yet implemented");
}
| OUTER_P
{ elog(ERROR,"OUTER JOIN not yet implemented"); }
{
$$ = LEFT;
elog(NOTICE,"OUTER JOIN not yet implemented");
}
| INNER_P
{ elog(ERROR,"INNER JOIN not yet implemented"); }
| UNION
{ elog(ERROR,"UNION JOIN not yet implemented"); }
{
$$ = INNER_P;
}
| /*EMPTY*/
{ elog(ERROR,"INNER JOIN not yet implemented"); }
{
$$ = INNER_P;
}
;
join_outer: OUTER_P { $$ = NULL; }
| /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
;
join_spec: ON '(' a_expr ')' { $$ = NULL; }
| USING '(' join_list ')' { $$ = NULL; }
| /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
/* JOIN qualification clauses
* Possibilities are:
* USING ( column list ) allows only unqualified column names,
* which must match between tables.
* ON expr allows more general qualifications.
* - thomas 1999-01-07
*/
join_qual: USING '(' using_list ')' { $$ = $3; }
| ON a_expr { $$ = lcons($2, NIL); }
;
join_list: join_using { $$ = lcons($1, NIL); }
| join_list ',' join_using { $$ = lappend($1, $3); }
using_list: using_list ',' using_expr { $$ = lappend($1, $3); }
| using_expr { $$ = lcons($1, NIL); }
;
join_using: ColId
/* Changed from SortGroupBy parse node to new JoinUsing node.
* SortGroupBy no longer needs these structure members.
*
* Once, acknowledged, this comment can be removed by the
* developer(s) working on the JOIN clause.
*
* - daveh@insightdist.com 1998-07-31
*/
{
$$ = makeNode(JoinUsing);
$$->resno = 0;
$$->range = NULL;
$$->name = $1;
}
| ColId '.' ColId
{
$$ = makeNode(JoinUsing);
$$->resno = 0;
$$->range = $1;
$$->name = $3;
}
| Iconst
using_expr: ColId
{
$$ = makeNode(JoinUsing);
$$->resno = $1;
$$->range = NULL;
$$->name = NULL;
/* could be a column name or a relation_name */
Ident *n = makeNode(Ident);
n->name = $1;
n->indirection = NULL;
$$ = (Node *)n;
}
;
......@@ -4737,12 +4795,15 @@ case_expr: CASE case_arg when_clause_list case_default END_TRANS
{
CaseExpr *c = makeNode(CaseExpr);
CaseWhen *w = makeNode(CaseWhen);
/*
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
w->result = (Node *)n;
*/
w->expr = makeA_Expr(OP, "=", $3, $5);
c->args = lcons(w, NIL);
c->defresult = $3;
w->expr = makeA_Expr(OP, "=", $3, $5);
$$ = (Node *)c;
elog(NOTICE,"NULLIF() not yet fully implemented");
}
| COALESCE '(' expr_list ')'
{
......@@ -4757,8 +4818,6 @@ case_expr: CASE case_arg when_clause_list case_default END_TRANS
c->args = lappend(c->args, w);
}
$$ = (Node *)c;
elog(NOTICE,"COALESCE() not yet fully implemented");
}
;
......@@ -5147,7 +5206,6 @@ ColLabel: ColId { $$ = $1; }
| COALESCE { $$ = "coalesce"; }
| CONSTRAINT { $$ = "constraint"; }
| COPY { $$ = "copy"; }
| CROSS { $$ = "cross"; }
| CURRENT { $$ = "current"; }
| DO { $$ = "do"; }
| ELSE { $$ = "else"; }
......@@ -5210,7 +5268,8 @@ makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
/* makeRowExpr()
* Generate separate operator nodes for a single row descriptor expression.
* Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
* Perhaps this should go deeper in the parser someday...
* - thomas 1997-12-22
*/
static Node *
makeRowExpr(char *opr, List *largs, List *rargs)
......@@ -5250,23 +5309,6 @@ makeRowExpr(char *opr, List *largs, List *rargs)
elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
}
#ifdef NOT_USED
while ((largs != NIL) && (rargs != NIL))
{
larg = lfirst(largs);
rarg = lfirst(rargs);
if (expr == NULL)
expr = makeA_Expr(OP, opr, larg, rarg);
else
expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
largs = lnext(largs);
rargs = lnext(rargs);
}
pprint(expr);
#endif
return expr;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment