Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0b69d8a

Browse files
committed
Rearrange top-level rewrite operations so that EXPLAIN works
on queries involving UNION, EXCEPT, INTERSECT.
1 parent6458daa commit0b69d8a

File tree

3 files changed

+122
-103
lines changed

3 files changed

+122
-103
lines changed

‎src/backend/commands/explain.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Copyright (c) 1994-5, Regents of the University of California
66
*
7-
* $Id: explain.c,v 1.35 1999/04/25 03:19:09 tgl Exp $
7+
* $Id: explain.c,v 1.36 1999/05/09 23:31:45 tgl Exp $
88
*
99
*/
1010
#include<stdio.h>
@@ -49,15 +49,18 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
4949
List*rewritten;
5050
List*l;
5151

52+
/* rewriter and planner may not work in aborted state? */
5253
if (IsAbortedTransactionBlockState())
5354
{
54-
char*tag="*ABORT STATE*";
55-
56-
EndCommand(tag,dest);
57-
5855
elog(NOTICE,"(transaction aborted): %s",
5956
"queries ignored until END");
57+
return;
58+
}
6059

60+
/* rewriter and planner will not cope with utility statements */
61+
if (query->commandType==CMD_UTILITY)
62+
{
63+
elog(NOTICE,"Utility statements have no plan structure");
6164
return;
6265
}
6366

@@ -67,7 +70,7 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
6770
/* In the case of an INSTEAD NOTHING, tell at least that */
6871
if (rewritten==NIL)
6972
{
70-
elog(NOTICE,"query rewrites to nothing");
73+
elog(NOTICE,"Query rewrites to nothing");
7174
return;
7275
}
7376

@@ -88,7 +91,7 @@ ExplainOneQuery(Query *query, bool verbose, CommandDest dest)
8891
Plan*plan;
8992
ExplainState*es;
9093

91-
/* plan thequeries (XXX we've ignored rewrite!!) */
94+
/* plan thequery */
9295
plan=planner(query);
9396

9497
/* pg_plan could have failed */
@@ -195,7 +198,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
195198
pname="Hash";
196199
break;
197200
default:
198-
pname="";
201+
pname="???";
199202
break;
200203
}
201204

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.37 1999/02/22 05:26:46momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.38 1999/05/09 23:31:46tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -59,8 +59,6 @@ static void modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_ind
5959
staticvoidmodifyAggrefDropQual(Node**nodePtr,Node*orignode,Expr*expr);
6060
staticSubLink*modifyAggrefMakeSublink(Expr*origexp,Query*parsetree);
6161
staticvoidmodifyAggrefQual(Node**nodePtr,Query*parsetree);
62-
63-
6462
staticQuery*fireRIRrules(Query*parsetree);
6563

6664

@@ -2634,12 +2632,12 @@ RewritePreprocessQuery(Query *parsetree)
26342632

26352633

26362634
/*
2637-
*QueryRewrite -
2635+
*BasicQueryRewrite -
26382636
* rewrite one query via query rewrite system, possibly returning 0
26392637
* or many queries
26402638
*/
2641-
List*
2642-
QueryRewrite(Query*parsetree)
2639+
staticList*
2640+
BasicQueryRewrite(Query*parsetree)
26432641
{
26442642
List*querylist;
26452643
List*results=NIL;
@@ -2672,10 +2670,57 @@ QueryRewrite(Query *parsetree)
26722670
}
26732671
returnresults;
26742672
}
2675-
/***S*I***/
2676-
/* This function takes two targetlists as arguments and checks if the targetlists are compatible
2677-
* (i.e. both select for the same number of attributes and the types are compatible
2673+
2674+
/*
2675+
* QueryRewrite -
2676+
* Primary entry point to the query rewriter.
2677+
* Rewrite one query via query rewrite system, possibly returning 0
2678+
* or many queries.
2679+
*
2680+
* NOTE: The code in QueryRewrite was formerly in pg_parse_and_plan(), and was
2681+
* moved here so that it would be invoked during EXPLAIN. The division of
2682+
* labor between this routine and BasicQueryRewrite is not obviously correct
2683+
* ... at least not to me ... tgl 5/99.
26782684
*/
2685+
List*
2686+
QueryRewrite(Query*parsetree)
2687+
{
2688+
List*rewritten,
2689+
*rewritten_item;
2690+
2691+
/***S*I***/
2692+
/* Rewrite Union, Intersect and Except Queries
2693+
* to normal Union Queries using IN and NOT IN subselects */
2694+
if (parsetree->intersectClause)
2695+
parsetree=Except_Intersect_Rewrite(parsetree);
2696+
2697+
/* Rewrite basic queries (retrieve, append, delete, replace) */
2698+
rewritten=BasicQueryRewrite(parsetree);
2699+
2700+
/*
2701+
* Rewrite the UNIONS.
2702+
*/
2703+
foreach (rewritten_item,rewritten)
2704+
{
2705+
Query*qry= (Query*)lfirst(rewritten_item);
2706+
List*union_result=NIL;
2707+
List*union_item;
2708+
2709+
foreach (union_item,qry->unionClause)
2710+
{
2711+
union_result=nconc(union_result,
2712+
BasicQueryRewrite((Query*)lfirst(union_item)));
2713+
}
2714+
qry->unionClause=union_result;
2715+
}
2716+
2717+
returnrewritten;
2718+
}
2719+
2720+
/***S*I***/
2721+
/* This function takes two targetlists as arguments and checks if the
2722+
* targetlists are compatible (i.e. both select for the same number of
2723+
* attributes and the types are compatible */
26792724
voidcheck_targetlists_are_compatible(List*prev_target,List*current_target)
26802725
{
26812726
List*next_target;

‎src/backend/tcop/postgres.c

Lines changed: 57 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.110 1999/05/03 19:09:54 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.111 1999/05/09 23:31:47 tgl Exp $
1111
*
1212
* NOTES
1313
* this is the "main" module of the postgres backend and
@@ -399,6 +399,49 @@ pg_parse_and_plan(char *query_string,/* string to execute */
399399
List*rewritten=NIL;
400400
Query*querytree;
401401

402+
if (DebugPrintQuery)
403+
{
404+
if (DebugPrintQuery>3)
405+
{
406+
/* Print the query string as is if query debug level > 3 */
407+
TPRINTF(TRACE_QUERY,"query: %s",query_string);
408+
}
409+
else
410+
{
411+
/* Print condensed query string to fit in one log line */
412+
charbuff[MAX_QUERY_SIZE+1];
413+
charc,
414+
*s,
415+
*d;
416+
intn,
417+
is_space=1;
418+
419+
for (s=query_string,d=buff,n=0; (c=*s)&& (n<MAX_QUERY_SIZE);s++)
420+
{
421+
switch (c)
422+
{
423+
case'\r':
424+
case'\n':
425+
case'\t':
426+
c=' ';
427+
/* fall through */
428+
case' ':
429+
if (is_space)
430+
continue;
431+
is_space=1;
432+
break;
433+
default:
434+
is_space=0;
435+
break;
436+
}
437+
*d++=c;
438+
n++;
439+
}
440+
*d='\0';
441+
TPRINTF(TRACE_QUERY,"query: %s",buff);
442+
}
443+
}
444+
402445
/* ----------------
403446
*(1) parse the request string into a list of parse trees
404447
* ----------------
@@ -421,104 +464,37 @@ pg_parse_and_plan(char *query_string,/* string to execute */
421464

422465
/* ----------------
423466
*(2) rewrite the queries, as necessary
467+
*
468+
* j counts queries output into new_list; the number of rewritten
469+
* queries can be different from the original number.
424470
* ----------------
425471
*/
426-
j=0;/* counter for the new_list, new_list can
427-
* be longer than old list as a result of
428-
* rewrites */
472+
j=0;
429473
for (i=0;i<querytree_list->len;i++)
430474
{
431-
List*union_result,
432-
*union_list,
433-
*rewritten_list;
434-
435475
querytree=querytree_list->qtrees[i];
436476

437-
/***S*I***/
438-
/* Rewrite Union, Intersect and Except Queries
439-
* to normal Union Queries using IN and NOT IN subselects */
440-
if(querytree->intersectClause!=NIL)
441-
{
442-
querytree=Except_Intersect_Rewrite(querytree);
443-
}
444-
445-
if (DebugPrintQuery)
477+
if (DebugPrintParse)
446478
{
447-
if (DebugPrintQuery>3)
448-
{
449-
/* Print the query string as is if query debug level > 3 */
450-
TPRINTF(TRACE_QUERY,"query: %s",query_string);
451-
}
452-
else
453-
{
454-
/* Print condensed query string to fit in one log line */
455-
charbuff[MAX_QUERY_SIZE+1];
456-
charc,
457-
*s,
458-
*d;
459-
intn,
460-
is_space=1;
461-
462-
for (s=query_string,d=buff,n=0; (c=*s)&& (n<MAX_QUERY_SIZE);s++)
463-
{
464-
switch (c)
465-
{
466-
case'\r':
467-
case'\n':
468-
case'\t':
469-
c=' ';
470-
/* fall through */
471-
case' ':
472-
if (is_space)
473-
continue;
474-
is_space=1;
475-
break;
476-
default:
477-
is_space=0;
478-
break;
479-
}
480-
*d++=c;
481-
n++;
482-
}
483-
*d='\0';
484-
TPRINTF(TRACE_QUERY,"query: %s",buff);
485-
}
479+
TPRINTF(TRACE_PARSE,"parser outputs:");
480+
nodeDisplay(querytree);
486481
}
487482

488-
/* don't rewrite utilites */
483+
/* don't rewrite utilites, just dump 'em into new_list */
489484
if (querytree->commandType==CMD_UTILITY)
490485
{
491486
new_list->qtrees[j++]=querytree;
492487
continue;
493488
}
494489

495-
if (DebugPrintParse)
496-
{
497-
TPRINTF(TRACE_PARSE,"parser outputs:");
498-
nodeDisplay(querytree);
499-
}
500-
501-
/* rewrite queries (retrieve, append, delete, replace) */
490+
/* rewrite regular queries */
502491
rewritten=QueryRewrite(querytree);
503492

504493
if (rewritten!=NIL)
505494
{
506495
intlen,
507496
k;
508497

509-
/*
510-
* Rewrite the UNIONS.
511-
*/
512-
foreach(rewritten_list,rewritten)
513-
{
514-
Query*qry= (Query*)lfirst(rewritten_list);
515-
516-
union_result=NIL;
517-
foreach(union_list,qry->unionClause)
518-
union_result=nconc(union_result,QueryRewrite((Query*)lfirst(union_list)));
519-
qry->unionClause=union_result;
520-
}
521-
522498
len=length(rewritten);
523499
if (len==1)
524500
new_list->qtrees[j++]= (Query*)lfirst(rewritten);
@@ -530,19 +506,14 @@ pg_parse_and_plan(char *query_string,/* string to execute */
530506
* we allocated one space
531507
* for the query */
532508
new_list->qtrees=realloc(new_list->qtrees,
533-
new_list->len*sizeof(Query*));
509+
new_list->len*sizeof(Query*));
534510
for (k=0;k<len;k++)
535511
new_list->qtrees[j++]= (Query*)nth(k,rewritten);
536512
}
537513
}
538514
}
539515

540-
/* ----------
541-
* Due to rewriting, the new list could also have been
542-
* shrunk (do instead nothing). Forget obsolete queries
543-
* at the end.
544-
* ----------
545-
*/
516+
/* Update new_list with correct final length */
546517
new_list->len=j;
547518

548519
/* we're done with the original lists, free it */
@@ -657,7 +628,7 @@ pg_parse_and_plan(char *query_string,/* string to execute */
657628
}
658629

659630
/* ----------
660-
* Check if the rewriting had thrown awayanything
631+
* Check if the rewriting had thrown awayeverything
661632
* ----------
662633
*/
663634
if (querytree_list->len==0)
@@ -1539,7 +1510,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
15391510
if (!IsUnderPostmaster)
15401511
{
15411512
puts("\nPOSTGRES backend interactive interface ");
1542-
puts("$Revision: 1.110 $ $Date: 1999/05/03 19:09:54 $\n");
1513+
puts("$Revision: 1.111 $ $Date: 1999/05/09 23:31:47 $\n");
15431514
}
15441515

15451516
/* ----------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp