Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
4ce24c8a
Commit
4ce24c8a
authored
Dec 27, 1997
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UNION work for UNION ALL and other union stuff.
parent
2730c4a4
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
178 additions
and
84 deletions
+178
-84
src/backend/executor/nodeAppend.c
src/backend/executor/nodeAppend.c
+22
-20
src/backend/nodes/outfuncs.c
src/backend/nodes/outfuncs.c
+2
-2
src/backend/nodes/readfuncs.c
src/backend/nodes/readfuncs.c
+2
-1
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/planner.c
+7
-9
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/prep/prepunion.c
+75
-43
src/backend/parser/analyze.c
src/backend/parser/analyze.c
+64
-5
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+4
-3
src/include/nodes/plannodes.h
src/include/nodes/plannodes.h
+2
-1
No files found.
src/backend/executor/nodeAppend.c
View file @
4ce24c8a
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.
9 1997/09/08 21:43:1
0 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.
10 1997/12/27 06:40:5
0 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -34,7 +34,7 @@
* nil nil ... ... ...
* subplans
*
* Append nodes are currently used to support inheritance
* Append nodes are currently used to
unions, and to
support inheritance
* queries, where several relations need to be scanned.
* For example, in our standard person/student/employee/student-emp
* example, where student and employee inherit from person
...
...
@@ -85,6 +85,7 @@ exec_append_initialize_next(Append *node)
int
whichplan
;
int
nplans
;
List
*
rts
;
List
*
rtentries
;
ResTarget
*
rtentry
;
...
...
@@ -101,6 +102,7 @@ exec_append_initialize_next(Append *node)
whichplan
=
unionstate
->
as_whichplan
;
nplans
=
unionstate
->
as_nplans
;
rts
=
node
->
unionrts
;
rtentries
=
node
->
unionrtentries
;
if
(
whichplan
<
0
)
...
...
@@ -140,27 +142,28 @@ exec_append_initialize_next(Append *node)
if
(
node
->
unionrelid
>
0
)
{
rtentry
=
nth
(
whichplan
,
rtentries
);
if
(
rtentry
==
NULL
)
elog
(
DEBUG
,
"exec_append_initialize_next: rtentry is nil"
);
Assert
(
rtentry
!=
NULL
);
unionrelid
=
node
->
unionrelid
;
rt_store
(
unionrelid
,
rangeTable
,
rtentry
);
if
(
unionstate
->
as_junkFilter_list
)
{
estate
->
es_junkFilter
=
(
JunkFilter
*
)
nth
(
whichplan
,
unionstate
->
as_junkFilter_list
);
}
if
(
unionstate
->
as_result_relation_info_list
)
{
estate
->
es_result_relation_info
=
(
RelationInfo
*
)
nth
(
whichplan
,
unionstate
->
as_result_relation_info_list
);
}
result_slot
->
ttc_whichplan
=
whichplan
;
}
else
estate
->
es_range_table
=
nth
(
whichplan
,
rts
);
if
(
unionstate
->
as_junkFilter_list
)
{
estate
->
es_junkFilter
=
(
JunkFilter
*
)
nth
(
whichplan
,
unionstate
->
as_junkFilter_list
);
}
if
(
unionstate
->
as_result_relation_info_list
)
{
estate
->
es_result_relation_info
=
(
RelationInfo
*
)
nth
(
whichplan
,
unionstate
->
as_result_relation_info_list
);
}
result_slot
->
ttc_whichplan
=
whichplan
;
return
TRUE
;
}
...
...
@@ -439,8 +442,7 @@ ExecProcAppend(Append *node)
if
(
exec_append_initialize_next
(
node
))
{
ExecSetSlotDescriptorIsNew
(
result_slot
,
true
);
return
ExecProcAppend
(
node
);
return
ExecProcAppend
(
node
);
}
else
return
ExecClearTuple
(
result_slot
);
...
...
src/backend/nodes/outfuncs.c
View file @
4ce24c8a
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.1
3 1997/12/23 19:50:54 thomas
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.1
4 1997/12/27 06:40:54 momjian
Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
...
...
@@ -194,7 +194,7 @@ _outQuery(StringInfo str, Query *node)
sprintf
(
buf
,
" :qual "
);
appendStringInfo
(
str
,
buf
);
_outNode
(
str
,
node
->
qual
);
/* how are we handling aggregates, sort, and group by? bjm 1997/12/26 */
}
/*
...
...
src/backend/nodes/readfuncs.c
View file @
4ce24c8a
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.1
1 1997/12/18 12:53
:59 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.1
2 1997/12/27 06:40
:59 momjian Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
...
...
@@ -119,6 +119,7 @@ _readQuery()
token
=
lsptok
(
NULL
,
&
length
);
/* skip :qual */
local_node
->
qual
=
nodeRead
(
true
);
/* how are we handling aggregates, sort, and group by? bjm 1997/12/26 */
return
(
local_node
);
}
...
...
src/backend/optimizer/plan/planner.c
View file @
4ce24c8a
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.1
6 1997/12/24 06:06:01
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.1
7 1997/12/27 06:41:07
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -72,8 +72,6 @@ planner(Query *parse)
{
List
*
tlist
=
parse
->
targetList
;
List
*
rangetable
=
parse
->
rtable
;
char
*
uniqueflag
=
parse
->
uniqueFlag
;
List
*
sortclause
=
parse
->
sortClause
;
Plan
*
result_plan
=
(
Plan
*
)
NULL
;
...
...
@@ -83,7 +81,7 @@ planner(Query *parse)
if
(
parse
->
unionClause
)
{
result_plan
=
(
Plan
*
)
plan_union_queries
(
0
,
/* none */
result_plan
=
(
Plan
*
)
plan_union_queries
(
0
,
/* none */
parse
,
UNION_FLAG
);
/* XXX do we need to do this? bjm 12/19/97 */
...
...
@@ -173,16 +171,16 @@ planner(Query *parse)
* the optimization step later.
*/
if
(
uniquef
lag
)
if
(
parse
->
uniqueF
lag
)
{
Plan
*
sortplan
=
make_sortplan
(
tlist
,
sortc
lause
,
result_plan
);
Plan
*
sortplan
=
make_sortplan
(
tlist
,
parse
->
sortC
lause
,
result_plan
);
return
((
Plan
*
)
make_unique
(
tlist
,
sortplan
,
uniquef
lag
));
return
((
Plan
*
)
make_unique
(
tlist
,
sortplan
,
parse
->
uniqueF
lag
));
}
else
{
if
(
sortc
lause
)
return
(
make_sortplan
(
tlist
,
sortc
lause
,
result_plan
));
if
(
parse
->
sortC
lause
)
return
(
make_sortplan
(
tlist
,
parse
->
sortC
lause
,
result_plan
));
else
return
((
Plan
*
)
result_plan
);
}
...
...
src/backend/optimizer/prep/prepunion.c
View file @
4ce24c8a
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.1
4 1997/12/26 06:02:26 vadim
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.1
5 1997/12/27 06:41:17 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -23,6 +23,7 @@
#include "nodes/relation.h"
#include "parser/parsetree.h"
#include "parser/parse_clause.h"
#include "utils/elog.h"
#include "utils/lsyscache.h"
...
...
@@ -42,7 +43,7 @@ static Query *subst_rangetable(Query *root, Index index,
RangeTblEntry
*
new_entry
);
static
void
fix_parsetree_attnums
(
Index
rt_index
,
Oid
old_relid
,
Oid
new_relid
,
Query
*
parsetree
);
static
Append
*
make_append
(
List
*
unionplans
,
Index
rt_index
,
static
Append
*
make_append
(
List
*
unionplans
,
List
*
unionrts
,
Index
rt_index
,
List
*
union_rt_entries
,
List
*
tlist
);
...
...
@@ -136,73 +137,102 @@ plan_union_queries(Index rt_index,
Query
*
parse
,
UnionFlag
flag
)
{
List
*
rangetable
=
parse
->
rtable
;
RangeTblEntry
*
rt_entry
=
rt_fetch
(
rt_index
,
rangetable
);
List
*
union_relids
=
NIL
;
List
*
union_plans
=
NIL
;
List
*
union_rt_entries
=
NIL
;
switch
(
flag
)
{
case
INHERITS_FLAG
:
union_relids
=
find_all_inheritors
(
lconsi
(
rt_entry
->
relid
,
NIL
),
NIL
);
/*
* Remove the flag for this relation, since we're about to handle it
* (do it before recursing!). XXX destructive parse tree change
*/
switch
(
flag
)
{
case
INHERITS_FLAG
:
rt_fetch
(
rt_index
,
rangetable
)
->
inh
=
false
;
break
;
default:
break
;
}
/*
* XXX - can't find any reason to sort union-relids as paul did, so
* we're leaving it out for now (maybe forever) - jeff & lp
*
* [maybe so. btw, jeff & lp did the lisp conversion, according to Paul.
* -- ay 10/94.]
*/
union_plans
=
plan_union_query
(
union_relids
,
rt_index
,
rt_entry
,
parse
,
flag
,
&
union_rt_entries
);
return
(
make_append
(
union_plans
,
rt_index
,
union_rt_entries
,
((
Plan
*
)
lfirst
(
union_plans
))
->
targetlist
));
break
;
List
*
rangetable
=
parse
->
rtable
;
RangeTblEntry
*
rt_entry
=
rt_fetch
(
rt_index
,
rangetable
);
List
*
union_rt_entries
=
NIL
;
List
*
union_relids
=
NIL
;
union_relids
=
find_all_inheritors
(
lconsi
(
rt_entry
->
relid
,
NIL
),
NIL
);
/*
* Remove the flag for this relation, since we're about to handle it
* (do it before recursing!). XXX destructive parse tree change
*/
switch
(
flag
)
{
case
INHERITS_FLAG
:
rt_fetch
(
rt_index
,
rangetable
)
->
inh
=
false
;
break
;
default:
break
;
}
/*
* XXX - can't find any reason to sort union-relids as paul did, so
* we're leaving it out for now (maybe forever) - jeff & lp
*
* [maybe so. btw, jeff & lp did the lisp conversion, according to Paul.
* -- ay 10/94.]
*/
union_plans
=
plan_union_query
(
union_relids
,
rt_index
,
rt_entry
,
parse
,
flag
,
&
union_rt_entries
);
return
(
make_append
(
union_plans
,
NULL
,
rt_index
,
union_rt_entries
,
((
Plan
*
)
lfirst
(
union_plans
))
->
targetlist
));
break
;
}
case
UNION_FLAG
:
{
List
*
ulist
,
*
hold_union
,
*
union_plans
;
List
*
ulist
,
*
hold_union
,
*
union_plans
,
*
union_rts
;
hold_union
=
parse
->
unionClause
;
parse
->
unionClause
=
NULL
;
/* prevent looping */
union_plans
=
lcons
(
planner
(
parse
),
NIL
);
union_rts
=
lcons
(
parse
->
rtable
,
NIL
);
foreach
(
ulist
,
hold_union
)
union_plans
=
lappend
(
union_plans
,
planner
(
lfirst
(
ulist
)));
return
(
make_append
(
union_plans
,
rt_index
,
rangetable
,
{
Query
*
u
=
lfirst
(
ulist
);
union_plans
=
lappend
(
union_plans
,
planner
(
u
));
union_rts
=
lappend
(
union_rts
,
u
->
rtable
);
}
/* We have already split UNION and UNION ALL */
if
(
!
((
Query
*
)
lfirst
(
hold_union
))
->
unionall
)
{
parse
->
uniqueFlag
=
"*"
;
parse
->
sortClause
=
transformSortClause
(
NULL
,
NIL
,
((
Plan
*
)
lfirst
(
union_plans
))
->
targetlist
,
"*"
);
}
else
{
/* needed so we don't take the flag from the first query */
parse
->
uniqueFlag
=
NULL
;
parse
->
sortClause
=
NIL
;
}
parse
->
havingQual
=
NULL
;
parse
->
qry_numAgg
=
0
;
parse
->
qry_aggs
=
NULL
;
return
(
make_append
(
union_plans
,
union_rts
,
rt_index
/* is 0, none */
,
NULL
,
((
Plan
*
)
lfirst
(
union_plans
))
->
targetlist
));
}
break
;
#ifdef NOT_USED
case
VERSION_FLAG
:
union_relids
=
VersionGetParents
(
rt_entry
->
relid
);
break
;
#endif
default:
/* do nothing */
break
;
}
return
NULL
;
return
((
Append
*
)
NULL
);
/* to make gcc happy */
}
...
...
@@ -392,6 +422,7 @@ fix_parsetree_attnums(Index rt_index,
static
Append
*
make_append
(
List
*
unionplans
,
List
*
unionrts
,
Index
rt_index
,
List
*
union_rt_entries
,
List
*
tlist
)
...
...
@@ -399,6 +430,7 @@ make_append(List *unionplans,
Append
*
node
=
makeNode
(
Append
);
node
->
unionplans
=
unionplans
;
node
->
unionrts
=
unionrts
;
node
->
unionrelid
=
rt_index
;
node
->
unionrtentries
=
union_rt_entries
;
node
->
plan
.
cost
=
0
.
0
;
...
...
src/backend/parser/analyze.c
View file @
4ce24c8a
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.5
6 1997/12/24 06:06:18
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.5
7 1997/12/27 06:41:26
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -839,16 +839,75 @@ transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
if
(
pstate
->
p_numAgg
>
0
)
finalizeAggregates
(
pstate
,
qry
);
qry
->
unionall
=
stmt
->
unionall
;
/* in child, so unionClause may be false */
if
(
stmt
->
unionClause
)
{
List
*
ulist
=
NIL
;
QueryTreeList
*
qlist
;
int
i
;
int
i
,
last_union
=
-
1
;
bool
union_all_found
=
false
,
union_found
=
false
;
qlist
=
parse_analyze
(
stmt
->
unionClause
);
/*
* Do we need to split up our unions because we have UNION
* and UNION ALL?
*/
for
(
i
=
0
;
i
<
qlist
->
len
;
i
++
)
ulist
=
lappend
(
ulist
,
qlist
->
qtrees
[
i
]);
qry
->
unionClause
=
ulist
;
{
if
(
qlist
->
qtrees
[
i
]
->
unionall
)
union_all_found
=
true
;
else
{
union_found
=
true
;
last_union
=
i
;
}
}
/* A trailing UNION negates the affect of earlier UNION ALLs */
if
(
!
union_all_found
||
!
union_found
||
/* last entry is a UNION */
!
qlist
->
qtrees
[
qlist
->
len
-
1
]
->
unionall
)
{
for
(
i
=
0
;
i
<
qlist
->
len
;
i
++
)
ulist
=
lappend
(
ulist
,
qlist
->
qtrees
[
i
]);
qry
->
unionClause
=
ulist
;
}
else
{
List
*
union_list
=
NIL
;
Query
*
hold_qry
;
/*
* We have mixed unions and non-unions, so we concentrate on
* the last UNION in the list.
*/
for
(
i
=
0
;
i
<=
last_union
;
i
++
)
{
qlist
->
qtrees
[
i
]
->
unionall
=
false
;
/*make queries consistent*/
union_list
=
lappend
(
union_list
,
qlist
->
qtrees
[
i
]);
}
/*
* Make the first UNION ALL after the last UNION our new
* top query
*/
hold_qry
=
qry
;
qry
=
qlist
->
qtrees
[
last_union
+
1
];
qry
->
unionClause
=
lcons
(
hold_qry
,
NIL
);
/* UNION queries */
hold_qry
->
unionall
=
true
;
/* UNION ALL this into other queries */
hold_qry
->
unionClause
=
union_list
;
/*
* The first UNION ALL after the last UNION is our anchor,
* we skip it.
*/
for
(
i
=
last_union
+
2
;
i
<
qlist
->
len
;
i
++
)
/* all queries are UNION ALL */
qry
->
unionClause
=
lappend
(
qry
->
unionClause
,
qlist
->
qtrees
[
i
]);
}
}
else
qry
->
unionClause
=
NULL
;
...
...
src/include/nodes/parsenodes.h
View file @
4ce24c8a
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.
39 1997/12/24 06:06:53
momjian Exp $
* $Id: parsenodes.h,v 1.
40 1997/12/27 06:41:39
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -43,7 +43,8 @@ typedef struct Query
char
*
into
;
/* portal (cursor) name */
bool
isPortal
;
/* is this a retrieve into portal? */
bool
isBinary
;
/* binary portal? */
bool
unionall
;
/* union without unique sort */
char
*
uniqueFlag
;
/* NULL, '*', or Unique attribute name */
List
*
sortClause
;
/* a list of SortClause's */
...
...
@@ -636,7 +637,7 @@ typedef struct RetrieveStmt
Node
*
havingClause
;
/* having conditional-expression */
List
*
unionClause
;
/* union subselect parameters */
List
*
sortClause
;
/* sort clause (a list of SortGroupBy's) */
int
unionall
;
/* union without unique sort */
bool
unionall
;
/* union without unique sort */
}
RetrieveStmt
;
...
...
src/include/nodes/plannodes.h
View file @
4ce24c8a
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: plannodes.h,v 1.1
1 1997/12/18 12:54:37
momjian Exp $
* $Id: plannodes.h,v 1.1
2 1997/12/27 06:41:41
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -119,6 +119,7 @@ typedef struct Append
{
Plan
plan
;
List
*
unionplans
;
List
*
unionrts
;
Index
unionrelid
;
List
*
unionrtentries
;
AppendState
*
unionstate
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment