~ubuntu-branches/ubuntu/utopic/pgadmin3/utopic-proposed

« back to all changes in this revision

Viewing changes to pgadmin/ctl/explainShape.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2011-06-07 23:03:54 UTC
  • mfrom: (1.3.1 upstream) (13 sid)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20110607230354-3td4j9y71u4ahcvj
Tags: 1.14.0~beta1-1
* New upstream development release, adding Build-Depends on
  postgresql-server-dev-all >= 117~.
* Add Build-Depends on quilt, (un)patch to debian/rules and patch for fixing
  the include for kwlist.h in pgadmin/db/keywords.c.
* Add pg_config --includedir-server output to CPPFLAGS.
* Remove unrecognized configure options: --with-wx-config,
  --with-pgsql-include, --enable-gtk2, --enable-unicode.
* Clean up manually the files that are left behind after the broken
  distclean.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//////////////////////////////////////////////////////////////////////////
2
2
//
3
3
// pgAdmin III - PostgreSQL Tools
4
 
// 
5
 
// Copyright (C) 2002 - 2010, The pgAdmin Development Team
 
4
//
 
5
// Copyright (C) 2002 - 2011, The pgAdmin Development Team
6
6
// This software is released under the PostgreSQL Licence
7
7
//
8
8
// explainShape.cpp - Explain Shapes
20
20
 
21
21
#include <wx/docview.h>
22
22
 
23
 
#include "images/ex_aggregate.xpm"
24
 
#include "images/ex_append.xpm"
25
 
#include "images/ex_bmp_heap.xpm"
26
 
#include "images/ex_bmp_index.xpm"
27
 
#include "images/ex_cte_scan.xpm"
28
 
#include "images/ex_group.xpm"
29
 
#include "images/ex_hash.xpm"
30
 
#include "images/ex_hash_anti_join.xpm"
31
 
#include "images/ex_hash_semi_join.xpm"
32
 
#include "images/ex_hash_setop_except.xpm"
33
 
#include "images/ex_hash_setop_except_all.xpm"
34
 
#include "images/ex_hash_setop_intersect.xpm"
35
 
#include "images/ex_hash_setop_intersect_all.xpm"
36
 
#include "images/ex_hash_setop_unknown.xpm"
37
 
#include "images/ex_index_scan.xpm"
38
 
#include "images/ex_join.xpm"
39
 
#include "images/ex_limit.xpm"
40
 
#include "images/ex_materialize.xpm"
41
 
#include "images/ex_merge.xpm"
42
 
#include "images/ex_merge_anti_join.xpm"
43
 
#include "images/ex_merge_semi_join.xpm"
44
 
#include "images/ex_nested.xpm"
45
 
#include "images/ex_nested_loop_anti_join.xpm"
46
 
#include "images/ex_nested_loop_semi_join.xpm"
47
 
#include "images/ex_recursive_union.xpm"
48
 
#include "images/ex_result.xpm"
49
 
#include "images/ex_scan.xpm"
50
 
#include "images/ex_seek.xpm"
51
 
#include "images/ex_setop.xpm"
52
 
#include "images/ex_sort.xpm"
53
 
#include "images/ex_subplan.xpm"
54
 
#include "images/ex_tid_scan.xpm"
55
 
#include "images/ex_unique.xpm"
56
 
#include "images/ex_unknown.xpm"
57
 
#include "images/ex_window_aggregate.xpm"
58
 
#include "images/ex_worktable_scan.xpm"
 
23
#include "images/ex_aggregate.pngc"
 
24
#include "images/ex_append.pngc"
 
25
#include "images/ex_bmp_heap.pngc"
 
26
#include "images/ex_bmp_index.pngc"
 
27
#include "images/ex_cte_scan.pngc"
 
28
#include "images/ex_group.pngc"
 
29
#include "images/ex_hash.pngc"
 
30
#include "images/ex_hash_anti_join.pngc"
 
31
#include "images/ex_hash_semi_join.pngc"
 
32
#include "images/ex_hash_setop_except.pngc"
 
33
#include "images/ex_hash_setop_except_all.pngc"
 
34
#include "images/ex_hash_setop_intersect.pngc"
 
35
#include "images/ex_hash_setop_intersect_all.pngc"
 
36
#include "images/ex_hash_setop_unknown.pngc"
 
37
#include "images/ex_index_scan.pngc"
 
38
#include "images/ex_join.pngc"
 
39
#include "images/ex_limit.pngc"
 
40
#include "images/ex_materialize.pngc"
 
41
#include "images/ex_merge.pngc"
 
42
#include "images/ex_merge_anti_join.pngc"
 
43
#include "images/ex_merge_semi_join.pngc"
 
44
#include "images/ex_nested.pngc"
 
45
#include "images/ex_nested_loop_anti_join.pngc"
 
46
#include "images/ex_nested_loop_semi_join.pngc"
 
47
#include "images/ex_recursive_union.pngc"
 
48
#include "images/ex_result.pngc"
 
49
#include "images/ex_scan.pngc"
 
50
#include "images/ex_seek.pngc"
 
51
#include "images/ex_setop.pngc"
 
52
#include "images/ex_sort.pngc"
 
53
#include "images/ex_subplan.pngc"
 
54
#include "images/ex_tid_scan.pngc"
 
55
#include "images/ex_unique.pngc"
 
56
#include "images/ex_unknown.pngc"
 
57
#include "images/ex_window_aggregate.pngc"
 
58
#include "images/ex_worktable_scan.pngc"
59
59
 
60
60
// Greenplum images
61
 
#include "images/ex_broadcast_motion.xpm"
62
 
#include "images/ex_redistribute_motion.xpm"
63
 
#include "images/ex_gather_motion.xpm"
 
61
#include "images/ex_broadcast_motion.pngc"
 
62
#include "images/ex_redistribute_motion.pngc"
 
63
#include "images/ex_gather_motion.pngc"
64
64
 
65
65
#define BMP_BORDER 3
66
66
 
67
 
ExplainShape::ExplainShape(const char *bmp[], const wxString &description, long tokenNo, long detailNo)
 
67
ExplainShape::ExplainShape(const wxImage &bmp, const wxString &description, long tokenNo, long detailNo)
68
68
{
69
 
    SetBitmap(wxBitmap(bmp));
70
 
    SetLabel(description, tokenNo, detailNo);
71
 
    kidCount=0;
72
 
    totalShapes=0;
73
 
    usedShapes=0;
 
69
        SetBitmap(wxBitmap(bmp));
 
70
        SetLabel(description, tokenNo, detailNo);
 
71
        kidCount = 0;
 
72
        totalShapes = 0;
 
73
        usedShapes = 0;
74
74
}
75
75
 
76
76
 
77
77
void ExplainShape::SetLabel(const wxString &str, int tokenNo, int detailNo)
78
78
{
79
 
    if (tokenNo < 0)
80
 
    {
81
 
        description = str;
82
 
        label = str;
83
 
    }
84
 
    else
85
 
    {
86
 
        wxStringTokenizer tokens(str, wxT(" "));
87
 
 
88
 
        while (tokenNo-- >= 0)
89
 
        {
90
 
            label = tokens.GetNextToken();
91
 
 
92
 
            if (detailNo <= 0)
93
 
            {
94
 
                if (!description.IsEmpty())
95
 
                    description.Append(wxT(" "));
96
 
            
97
 
                description.Append(label);
98
 
            }
99
 
        }
100
 
        if (detailNo > 0)
101
 
        {
102
 
            tokens.SetString(str, wxT(" "));
103
 
 
104
 
            while (detailNo--)
105
 
            {
106
 
                if (!description.IsEmpty())
107
 
                    description.Append(wxT(" "));
108
 
                
109
 
                description.Append(tokens.GetNextToken());
110
 
            }
111
 
            detail = tokens.GetString();
112
 
        }
113
 
    }
 
79
        if (tokenNo < 0)
 
80
        {
 
81
                description = str;
 
82
                label = str;
 
83
        }
 
84
        else
 
85
        {
 
86
                wxStringTokenizer tokens(str, wxT(" "));
 
87
 
 
88
                while (tokenNo-- >= 0)
 
89
                {
 
90
                        label = tokens.GetNextToken();
 
91
 
 
92
                        if (detailNo <= 0)
 
93
                        {
 
94
                                if (!description.IsEmpty())
 
95
                                        description.Append(wxT(" "));
 
96
 
 
97
                                description.Append(label);
 
98
                        }
 
99
                }
 
100
                if (detailNo > 0)
 
101
                {
 
102
                        tokens.SetString(str, wxT(" "));
 
103
 
 
104
                        while (detailNo--)
 
105
                        {
 
106
                                if (!description.IsEmpty())
 
107
                                        description.Append(wxT(" "));
 
108
 
 
109
                                description.Append(tokens.GetNextToken());
 
110
                        }
 
111
                        detail = tokens.GetString();
 
112
                }
 
113
        }
114
114
}
115
115
 
116
 
void ExplainShape::OnDraw(wxDC& dc)
 
116
void ExplainShape::OnDraw(wxDC &dc)
117
117
{
118
 
    wxBitmap &bmp=GetBitmap();
119
 
    if (!bmp.Ok())
120
 
        return;
121
 
 
122
 
    int x, y;
123
 
    x = WXROUND(m_xpos - bmp.GetWidth() / 2.0);
124
 
    y = WXROUND(m_ypos - GetHeight() / 2.0);
125
 
 
126
 
    dc.DrawBitmap(bmp, x, y, true);
127
 
 
128
 
    int w, h;
129
 
    dc.SetFont(GetCanvas()->GetFont());
130
 
    dc.GetTextExtent(label, &w, &h);
131
 
 
132
 
    x = WXROUND(m_xpos - w / 2.0);
133
 
    y +=bmp.GetHeight() + BMP_BORDER;
134
 
 
135
 
    dc.DrawText(label, x, y);
 
118
        wxBitmap &bmp = GetBitmap();
 
119
        if (!bmp.Ok())
 
120
                return;
 
121
 
 
122
        int x, y;
 
123
        x = WXROUND(m_xpos - bmp.GetWidth() / 2.0);
 
124
        y = WXROUND(m_ypos - GetHeight() / 2.0);
 
125
 
 
126
        dc.DrawBitmap(bmp, x, y, true);
 
127
 
 
128
        int w, h;
 
129
        dc.SetFont(GetCanvas()->GetFont());
 
130
        dc.GetTextExtent(label, &w, &h);
 
131
 
 
132
        x = WXROUND(m_xpos - w / 2.0);
 
133
        y += bmp.GetHeight() + BMP_BORDER;
 
134
 
 
135
        dc.DrawText(label, x, y);
136
136
}
137
137
 
138
138
 
139
139
void ExplainShape::OnLeftClick(double x, double y, int keys, int attachment)
140
140
{
141
 
    ((ExplainCanvas*)GetCanvas())->ShowPopup(this);
 
141
        ((ExplainCanvas *)GetCanvas())->ShowPopup(this);
142
142
}
143
143
 
144
144
 
145
145
#define ARROWMARGIN 5
146
146
wxRealPoint ExplainShape::GetStartPoint()
147
147
{
148
 
    wxRealPoint rp(GetX() + GetBitmap().GetWidth() / 2.0 + ARROWMARGIN, GetY() - (GetHeight()-GetBitmap().GetHeight()) / 2.);
149
 
    return rp;
 
148
        wxRealPoint rp(GetX() + GetBitmap().GetWidth() / 2.0 + ARROWMARGIN, GetY() - (GetHeight() - GetBitmap().GetHeight()) / 2.);
 
149
        return rp;
150
150
}
151
151
 
152
152
 
153
153
wxRealPoint ExplainShape::GetEndPoint(int kidNo)
154
154
{
155
 
    wxRealPoint rp(GetX() - GetBitmap().GetWidth() / 2.0 - ARROWMARGIN, GetY() - (GetHeight()-GetBitmap().GetHeight()) / 2. + (kidCount>1 ? GetBitmap().GetHeight() * 2. /3. * kidNo / (2*kidCount-2) : 0 ));
156
 
    return rp;
 
155
        wxRealPoint rp(GetX() - GetBitmap().GetWidth() / 2.0 - ARROWMARGIN, GetY() - (GetHeight() - GetBitmap().GetHeight()) / 2. + (kidCount > 1 ? GetBitmap().GetHeight() * 2. / 3. * kidNo / (2 * kidCount - 2) : 0 ));
 
156
        return rp;
157
157
}
158
158
 
159
159
 
160
160
 
161
161
ExplainShape *ExplainShape::Create(long level, ExplainShape *last, const wxString &str)
162
162
{
163
 
    ExplainShape *s=0;
164
 
 
165
 
    int costPos=str.Find(wxT("(cost="));
166
 
    int actPos = str.Find(wxT("(actual"));
167
 
 
168
 
    wxStringTokenizer tokens(str, wxT(" "));
169
 
    wxString token = tokens.GetNextToken();
170
 
    wxString token2 = tokens.GetNextToken();
171
 
    wxString token3 = tokens.GetNextToken();
172
 
    wxString token4;
173
 
    if (tokens.HasMoreTokens())
174
 
        token4 = tokens.GetNextToken();
175
 
    wxString descr;
176
 
    if (costPos > 0)
177
 
        descr = str.Left(costPos);
178
 
    else if (actPos > 0)
179
 
        descr = str.Left(actPos);
180
 
    else
181
 
        descr = str;
182
 
 
183
 
    // possible keywords can be found in postgresql/src/backend/commands/explain.c
184
 
 
185
 
    if (token == wxT("Total"))              return 0;
186
 
    else if (token == wxT("Trigger"))       return 0;
187
 
    else if (token == wxT("Settings:"))         return 0;               /* Greenplum */
188
 
    else if (token == wxT("Slice"))                     return 0;               /* Greenplum */
189
 
    else if (token.Mid(0,6) == wxT("(slice"))   return 0;       /* Greenplum */
190
 
    else if (token == wxT("Result"))        s = new ExplainShape(ex_result_xpm, descr);
191
 
    else if (token == wxT("Append"))        s = new ExplainShape(ex_append_xpm, descr);
192
 
    else if (token == wxT("Nested"))
193
 
    {
194
 
        if (token2 == wxT("Loop") && token4 == wxT("Join"))
195
 
        {
196
 
            // Nested Loop Anti Join
197
 
            if (token3 == wxT("Anti"))
198
 
            {
199
 
                s = new ExplainShape(ex_nested_loop_anti_join_xpm, descr);
200
 
            }
201
 
            // Nested Loop Semi Join
202
 
            else
203
 
            {
204
 
                s = new ExplainShape(ex_nested_loop_semi_join_xpm, descr);
205
 
            }
206
 
        }
207
 
        if (!s)
208
 
            s = new ExplainShape(ex_nested_xpm, descr);
209
 
    }
210
 
    else if (token == wxT("Merge"))
211
 
    {
212
 
        if (token3 == wxT("Join"))
213
 
        {
214
 
            // Merge Anti Join
215
 
            if (token2 == wxT("Anti"))
216
 
            {
217
 
                s = new ExplainShape(ex_merge_anti_join_xpm, descr);
218
 
            }
219
 
            // Merge Semi Join
220
 
            else
221
 
            {
222
 
                s = new ExplainShape(ex_merge_semi_join_xpm, descr);
223
 
            }
224
 
        }
225
 
        else
226
 
        {
227
 
            s = new ExplainShape(ex_merge_xpm, descr);
228
 
        }
229
 
    }
230
 
    else if (token == wxT("Hash"))
231
 
    {
232
 
        if (token2 == wxT("Join"))
233
 
        {
234
 
            s = new ExplainShape(ex_join_xpm, descr);
235
 
        }
236
 
        else
237
 
        {
238
 
            if (token3 == wxT("Join"))
239
 
            {
240
 
                // Hash Anti Join
241
 
                if (token2 == wxT("Anti"))
242
 
                {
243
 
                    s = new ExplainShape(ex_hash_anti_join_xpm, descr);
244
 
                }
245
 
                // Hash Semi Join
246
 
                else if (token2 == wxT("Semi"))
247
 
                {
248
 
                    s = new ExplainShape(ex_hash_semi_join_xpm, descr);
249
 
                }
250
 
                else
251
 
                {
252
 
                    s = new ExplainShape(ex_hash_xpm, descr);
253
 
                }
254
 
            }
255
 
            else
256
 
            {
257
 
                s = new ExplainShape(ex_hash_xpm, descr);
258
 
            }
259
 
        }
260
 
    }
261
 
    else if (token == wxT("HashSetOp"))
262
 
    {
263
 
        if (token2 == wxT("Except"))
264
 
        {
265
 
            // HashSetOp Except ALL
266
 
            if (token3 == wxT("ALL"))
267
 
            {
268
 
                s = new ExplainShape(ex_hash_setop_except_all_xpm, descr);
269
 
            }
270
 
            // HashSetOp Except
271
 
            else
272
 
            {
273
 
                s = new ExplainShape(ex_hash_setop_except_xpm, descr);
274
 
            }
275
 
        }
276
 
        else if (token2 == wxT("Intersect"))
277
 
        {
278
 
            // HashSetOp Intersect ALL
279
 
            if (token3 == wxT("ALL"))
280
 
            {
281
 
                s = new ExplainShape(ex_hash_setop_intersect_all_xpm, descr);
282
 
            }
283
 
            // HashSetOp Intersect
284
 
            else
285
 
            {
286
 
                s = new ExplainShape(ex_hash_setop_intersect_xpm, descr);
287
 
            }
288
 
        }
289
 
        else
290
 
        {
291
 
           // HashSetOp ???
292
 
           s = new ExplainShape(ex_hash_setop_unknown_xpm, descr);
293
 
        }
294
 
    }
295
 
    else if (token == wxT("Subquery"))      s = new ExplainShape(ex_subplan_xpm, descr, 0, 2);
296
 
    else if (token == wxT("Function"))      s = new ExplainShape(ex_result_xpm, descr, 0, 2);
297
 
    else if (token == wxT("Materialize"))   s = new ExplainShape(ex_materialize_xpm, descr);
298
 
    else if (token == wxT("Sort"))          s = new ExplainShape(ex_sort_xpm, descr);
299
 
    else if (token == wxT("Group"))         s = new ExplainShape(ex_group_xpm, descr);
300
 
    else if (token == wxT("Aggregate") || token == wxT("GroupAggregate") || token == wxT("HashAggregate"))
301
 
        s = new ExplainShape(ex_aggregate_xpm, descr);
302
 
    else if (token == wxT("Unique"))        s = new ExplainShape(ex_unique_xpm, descr);
303
 
    else if (token == wxT("SetOp"))         s = new ExplainShape(ex_setop_xpm, descr);
304
 
    else if (token == wxT("Limit"))         s = new ExplainShape(ex_limit_xpm, descr);
305
 
    else if (token == wxT("Bitmap"))
306
 
    {
307
 
        if (token2 == wxT("Index"))         s = new ExplainShape(ex_bmp_index_xpm, descr, 4, 3);
308
 
        else                                s = new ExplainShape(ex_bmp_heap_xpm, descr, 4, 3);
309
 
    }
310
 
    else if (token2 == wxT("Scan"))
311
 
    {
312
 
        if (token == wxT("Index"))
313
 
            // Scan Index Backword
314
 
            if (token3 == wxT("Backward"))
315
 
                s = new ExplainShape(ex_index_scan_xpm, descr, 4, 3);
316
 
            else
317
 
                s = new ExplainShape(ex_index_scan_xpm, descr, 3, 2);
318
 
        // Tid Scan
319
 
        else if (token == wxT("Tid"))
320
 
            s = new ExplainShape(ex_tid_scan_xpm, descr, 3, 2);
321
 
        // WorkTable scan
322
 
        else if (token == wxT("WorkTable"))
323
 
            s = new ExplainShape(ex_worktable_scan_xpm, descr, 3, 2);
324
 
        // CTE Scan
325
 
        else if (token == wxT("CTE"))
326
 
            s = new ExplainShape(ex_cte_scan_xpm, descr, 3, 2);
327
 
        else
328
 
            s = new ExplainShape(ex_scan_xpm, descr, 3, 2);
329
 
    }
330
 
    else if (token2 == wxT("Seek"))         s = new ExplainShape(ex_seek_xpm, descr, 3, 2);
331
 
     // Recursive Union
332
 
    else if (token == wxT("Recursive") && token2 == wxT("Union"))
333
 
        s = new ExplainShape(ex_recursive_union_xpm, descr);
334
 
    else if (token == wxT("WindowAgg"))
335
 
        s = new ExplainShape(ex_window_aggregate_xpm, descr);
336
 
 
337
 
    // Greenplum additions
338
 
    else if (token == wxT("Gather") && token2 ==wxT("Motion"))
339
 
        s = new ExplainShape(ex_gather_motion_xpm, descr);
340
 
    else if (token == wxT("Broadcast") && token2 ==wxT("Motion"))
341
 
        s = new ExplainShape(ex_broadcast_motion_xpm, descr);
342
 
    else if (token == wxT("Redistribute") && token2 ==wxT("Motion"))
343
 
        s = new ExplainShape(ex_redistribute_motion_xpm, descr);
344
 
 
345
 
    if (!s)
346
 
        s = new ExplainShape(ex_unknown_xpm, descr);
347
 
    
348
 
    s->SetDraggable(false);
349
 
 
350
 
    s->level = level;
351
 
 
352
 
    if (costPos > 0)
353
 
    {
354
 
        if (actPos > 0)
355
 
        {
356
 
            s->actual = str.Mid(actPos);
357
 
            s->cost = str.Mid(costPos, actPos-costPos);
358
 
        }
359
 
        else
360
 
            s->cost = str.Mid(costPos);
361
 
    }
362
 
    else if (actPos > 0)
363
 
        s->actual = str.Mid(actPos);
364
 
    
365
 
    int w=50, h=20;
366
 
 
367
 
    wxBitmap &bmp=s->GetBitmap();
368
 
    if (w < bmp.GetWidth())
369
 
        w = bmp.GetWidth();
370
 
 
371
 
    s->SetHeight(bmp.GetHeight() + BMP_BORDER + h);
372
 
    s->SetWidth(w);
373
 
 
374
 
    s->upperShape = last;
375
 
    if (last)
376
 
    {
377
 
        s->kidNo = last->kidCount;
378
 
        last->kidCount++;
379
 
    }
380
 
    else
381
 
        s->kidNo = 0;
382
 
 
383
 
    if (costPos > 0)
384
 
    {
385
 
        wxChar *cl=(wxChar*)str.c_str() + costPos+6;
386
 
        wxChar *ch=wxStrstr(cl, wxT(".."));
387
 
        if (ch)
388
 
        {
389
 
            *ch=0;
390
 
            ch += 2;
391
 
        }
392
 
        s->costLow = StrToDouble(cl);
393
 
        if (ch)
394
 
        {
395
 
            wxChar *r=wxStrstr(ch, wxT(" rows="));
396
 
            if (r)
397
 
            {
398
 
                *r=0;
399
 
                r += 6;
400
 
            }
401
 
            s->costHigh = StrToDouble(ch);
402
 
            if (r)
403
 
            {
404
 
                wxChar *w=wxStrstr(r, wxT(" width="));
405
 
                if (w)
406
 
                {
407
 
                    *w=0;
408
 
                    w += 7;
409
 
                }
410
 
                s->rows = StrToLong(r);
411
 
                if (w)
412
 
                    s->width = StrToLong(w);
413
 
            }
414
 
        }
415
 
    }
416
 
    return s;
 
163
        ExplainShape *s = 0;
 
164
 
 
165
        int costPos = str.Find(wxT("(cost="));
 
166
        int actPos = str.Find(wxT("(actual"));
 
167
 
 
168
        wxStringTokenizer tokens(str, wxT(" "));
 
169
        wxString token = tokens.GetNextToken();
 
170
        wxString token2 = tokens.GetNextToken();
 
171
        wxString token3 = tokens.GetNextToken();
 
172
        wxString token4;
 
173
        if (tokens.HasMoreTokens())
 
174
                token4 = tokens.GetNextToken();
 
175
        wxString descr;
 
176
        if (costPos > 0)
 
177
                descr = str.Left(costPos);
 
178
        else if (actPos > 0)
 
179
                descr = str.Left(actPos);
 
180
        else
 
181
                descr = str;
 
182
 
 
183
        // possible keywords can be found in postgresql/src/backend/commands/explain.c
 
184
 
 
185
        if (token == wxT("Total"))              return 0;
 
186
        else if (token == wxT("Trigger"))       return 0;
 
187
        else if (token == wxT("Settings:"))             return 0;               /* Greenplum */
 
188
        else if (token == wxT("Slice"))                 return 0;               /* Greenplum */
 
189
        else if (token.Mid(0, 6) == wxT("(slice"))      return 0;       /* Greenplum */
 
190
        else if (token == wxT("Result"))        s = new ExplainShape(*ex_result_png_img, descr);
 
191
        else if (token == wxT("Append"))        s = new ExplainShape(*ex_append_png_img, descr);
 
192
        else if (token == wxT("Nested"))
 
193
        {
 
194
                if (token2 == wxT("Loop") && token4 == wxT("Join"))
 
195
                {
 
196
                        // Nested Loop Anti Join
 
197
                        if (token3 == wxT("Anti"))
 
198
                        {
 
199
                                s = new ExplainShape(*ex_nested_loop_anti_join_png_img, descr);
 
200
                        }
 
201
                        // Nested Loop Semi Join
 
202
                        else
 
203
                        {
 
204
                                s = new ExplainShape(*ex_nested_loop_semi_join_png_img, descr);
 
205
                        }
 
206
                }
 
207
                if (!s)
 
208
                        s = new ExplainShape(*ex_nested_png_img, descr);
 
209
        }
 
210
        else if (token == wxT("Merge"))
 
211
        {
 
212
                if (token3 == wxT("Join"))
 
213
                {
 
214
                        // Merge Anti Join
 
215
                        if (token2 == wxT("Anti"))
 
216
                        {
 
217
                                s = new ExplainShape(*ex_merge_anti_join_png_img, descr);
 
218
                        }
 
219
                        // Merge Semi Join
 
220
                        else
 
221
                        {
 
222
                                s = new ExplainShape(*ex_merge_semi_join_png_img, descr);
 
223
                        }
 
224
                }
 
225
                else
 
226
                {
 
227
                        s = new ExplainShape(*ex_merge_png_img, descr);
 
228
                }
 
229
        }
 
230
        else if (token == wxT("Hash"))
 
231
        {
 
232
                if (token2 == wxT("Join"))
 
233
                {
 
234
                        s = new ExplainShape(*ex_join_png_img, descr);
 
235
                }
 
236
                else
 
237
                {
 
238
                        if (token3 == wxT("Join"))
 
239
                        {
 
240
                                // Hash Anti Join
 
241
                                if (token2 == wxT("Anti"))
 
242
                                {
 
243
                                        s = new ExplainShape(*ex_hash_anti_join_png_img, descr);
 
244
                                }
 
245
                                // Hash Semi Join
 
246
                                else if (token2 == wxT("Semi"))
 
247
                                {
 
248
                                        s = new ExplainShape(*ex_hash_semi_join_png_img, descr);
 
249
                                }
 
250
                                else
 
251
                                {
 
252
                                        s = new ExplainShape(*ex_hash_png_img, descr);
 
253
                                }
 
254
                        }
 
255
                        else
 
256
                        {
 
257
                                s = new ExplainShape(*ex_hash_png_img, descr);
 
258
                        }
 
259
                }
 
260
        }
 
261
        else if (token == wxT("HashSetOp"))
 
262
        {
 
263
                if (token2 == wxT("Except"))
 
264
                {
 
265
                        // HashSetOp Except ALL
 
266
                        if (token3 == wxT("ALL"))
 
267
                        {
 
268
                                s = new ExplainShape(*ex_hash_setop_except_all_png_img, descr);
 
269
                        }
 
270
                        // HashSetOp Except
 
271
                        else
 
272
                        {
 
273
                                s = new ExplainShape(*ex_hash_setop_except_png_img, descr);
 
274
                        }
 
275
                }
 
276
                else if (token2 == wxT("Intersect"))
 
277
                {
 
278
                        // HashSetOp Intersect ALL
 
279
                        if (token3 == wxT("ALL"))
 
280
                        {
 
281
                                s = new ExplainShape(*ex_hash_setop_intersect_all_png_img, descr);
 
282
                        }
 
283
                        // HashSetOp Intersect
 
284
                        else
 
285
                        {
 
286
                                s = new ExplainShape(*ex_hash_setop_intersect_png_img, descr);
 
287
                        }
 
288
                }
 
289
                else
 
290
                {
 
291
                        // HashSetOp ???
 
292
                        s = new ExplainShape(*ex_hash_setop_unknown_png_img, descr);
 
293
                }
 
294
        }
 
295
        else if (token == wxT("Subquery"))      s = new ExplainShape(*ex_subplan_png_img, descr, 0, 2);
 
296
        else if (token == wxT("Function"))      s = new ExplainShape(*ex_result_png_img, descr, 0, 2);
 
297
        else if (token == wxT("Materialize"))   s = new ExplainShape(*ex_materialize_png_img, descr);
 
298
        else if (token == wxT("Sort"))          s = new ExplainShape(*ex_sort_png_img, descr);
 
299
        else if (token == wxT("Group"))         s = new ExplainShape(*ex_group_png_img, descr);
 
300
        else if (token == wxT("Aggregate") || token == wxT("GroupAggregate") || token == wxT("HashAggregate"))
 
301
                s = new ExplainShape(*ex_aggregate_png_img, descr);
 
302
        else if (token == wxT("Unique"))        s = new ExplainShape(*ex_unique_png_img, descr);
 
303
        else if (token == wxT("SetOp"))         s = new ExplainShape(*ex_setop_png_img, descr);
 
304
        else if (token == wxT("Limit"))         s = new ExplainShape(*ex_limit_png_img, descr);
 
305
        else if (token == wxT("Bitmap"))
 
306
        {
 
307
                if (token2 == wxT("Index"))         s = new ExplainShape(*ex_bmp_index_png_img, descr, 4, 3);
 
308
                else                                s = new ExplainShape(*ex_bmp_heap_png_img, descr, 4, 3);
 
309
        }
 
310
        else if (token2 == wxT("Scan"))
 
311
        {
 
312
                if (token == wxT("Index"))
 
313
                        // Scan Index Backword
 
314
                        if (token3 == wxT("Backward"))
 
315
                                s = new ExplainShape(*ex_index_scan_png_img, descr, 4, 3);
 
316
                        else
 
317
                                s = new ExplainShape(*ex_index_scan_png_img, descr, 3, 2);
 
318
                // Tid Scan
 
319
                else if (token == wxT("Tid"))
 
320
                        s = new ExplainShape(*ex_tid_scan_png_img, descr, 3, 2);
 
321
                // WorkTable scan
 
322
                else if (token == wxT("WorkTable"))
 
323
                        s = new ExplainShape(*ex_worktable_scan_png_img, descr, 3, 2);
 
324
                // CTE Scan
 
325
                else if (token == wxT("CTE"))
 
326
                        s = new ExplainShape(*ex_cte_scan_png_img, descr, 3, 2);
 
327
                else
 
328
                        s = new ExplainShape(*ex_scan_png_img, descr, 3, 2);
 
329
        }
 
330
        else if (token2 == wxT("Seek"))         s = new ExplainShape(*ex_seek_png_img, descr, 3, 2);
 
331
        // Recursive Union
 
332
        else if (token == wxT("Recursive") && token2 == wxT("Union"))
 
333
                s = new ExplainShape(*ex_recursive_union_png_img, descr);
 
334
        else if (token == wxT("WindowAgg"))
 
335
                s = new ExplainShape(*ex_window_aggregate_png_img, descr);
 
336
 
 
337
        // Greenplum additions
 
338
        else if (token == wxT("Gather") && token2 == wxT("Motion"))
 
339
                s = new ExplainShape(*ex_gather_motion_png_img, descr);
 
340
        else if (token == wxT("Broadcast") && token2 == wxT("Motion"))
 
341
                s = new ExplainShape(*ex_broadcast_motion_png_img, descr);
 
342
        else if (token == wxT("Redistribute") && token2 == wxT("Motion"))
 
343
                s = new ExplainShape(*ex_redistribute_motion_png_img, descr);
 
344
 
 
345
        if (!s)
 
346
                s = new ExplainShape(*ex_unknown_png_img, descr);
 
347
 
 
348
        s->SetDraggable(false);
 
349
 
 
350
        s->level = level;
 
351
 
 
352
        if (costPos > 0)
 
353
        {
 
354
                if (actPos > 0)
 
355
                {
 
356
                        s->actual = str.Mid(actPos);
 
357
                        s->cost = str.Mid(costPos, actPos - costPos);
 
358
                }
 
359
                else
 
360
                        s->cost = str.Mid(costPos);
 
361
        }
 
362
        else if (actPos > 0)
 
363
                s->actual = str.Mid(actPos);
 
364
 
 
365
        int w = 50, h = 20;
 
366
 
 
367
        wxBitmap &bmp = s->GetBitmap();
 
368
        if (w < bmp.GetWidth())
 
369
                w = bmp.GetWidth();
 
370
 
 
371
        s->SetHeight(bmp.GetHeight() + BMP_BORDER + h);
 
372
        s->SetWidth(w);
 
373
 
 
374
        s->upperShape = last;
 
375
        if (last)
 
376
        {
 
377
                s->kidNo = last->kidCount;
 
378
                last->kidCount++;
 
379
        }
 
380
        else
 
381
                s->kidNo = 0;
 
382
 
 
383
        if (costPos > 0)
 
384
        {
 
385
                wxChar *cl = const_cast<wxChar *>((const wxChar *)str + costPos + 6);
 
386
                wxChar *ch = wxStrstr(cl, wxT(".."));
 
387
                if (ch)
 
388
                {
 
389
                        *ch = 0;
 
390
                        ch += 2;
 
391
                }
 
392
                s->costLow = StrToDouble(cl);
 
393
                if (ch)
 
394
                {
 
395
                        wxChar *r = wxStrstr(ch, wxT(" rows="));
 
396
                        if (r)
 
397
                        {
 
398
                                *r = 0;
 
399
                                r += 6;
 
400
                        }
 
401
                        s->costHigh = StrToDouble(ch);
 
402
                        if (r)
 
403
                        {
 
404
                                wxChar *w = wxStrstr(r, wxT(" width="));
 
405
                                if (w)
 
406
                                {
 
407
                                        *w = 0;
 
408
                                        w += 7;
 
409
                                }
 
410
                                s->rows = StrToLong(r);
 
411
                                if (w)
 
412
                                        s->width = StrToLong(w);
 
413
                        }
 
414
                }
 
415
        }
 
416
        return s;
417
417
}
418
418
 
419
419
 
420
420
ExplainLine::ExplainLine(ExplainShape *from, ExplainShape *to, double weight)
421
421
{
422
 
    SetCanvas(from->GetCanvas());
423
 
    from->AddLine(this, to);
424
 
    MakeLineControlPoints(4);
425
 
 
426
 
    width = (int) log(from->GetAverageCost());
427
 
    if (width > 10)
428
 
        width = 10;
429
 
 
430
 
    // If we got an average cost of 0, width is probably negative
431
 
    // which will look pretty darn ugly as an arrow width!
432
 
    // This may happen on Greenplum.
433
 
    if (width < 1)
434
 
        width = 1;
435
 
 
436
 
    wxNode *first = GetLineControlPoints()->GetFirst();
437
 
    wxNode *last  = GetLineControlPoints()->GetLast();
438
 
    *(wxRealPoint *)first->GetData() = from->GetStartPoint();
439
 
    *(wxRealPoint *)last->GetData() = to->GetEndPoint(from->GetKidno());
440
 
 
441
 
    wxRealPoint *p1=(wxRealPoint *)first->GetNext()->GetData();
442
 
    wxRealPoint *p2=(wxRealPoint *)last->GetPrevious()->GetData();
443
 
    *p1 = from->GetStartPoint();
444
 
    *p2 = to->GetEndPoint(from->GetKidno());
445
 
    p1->x -= (p1->x - p2->x)/3. +8;
446
 
    p2->x += (p1->x - p2->x)/3. -8;
447
 
 
448
 
    Initialise();
 
422
        SetCanvas(from->GetCanvas());
 
423
        from->AddLine(this, to);
 
424
        MakeLineControlPoints(4);
 
425
 
 
426
        width = (int) log(from->GetAverageCost());
 
427
        if (width > 10)
 
428
                width = 10;
 
429
 
 
430
        // If we got an average cost of 0, width is probably negative
 
431
        // which will look pretty darn ugly as an arrow width!
 
432
        // This may happen on Greenplum.
 
433
        if (width < 1)
 
434
                width = 1;
 
435
 
 
436
        wxNode *first = GetLineControlPoints()->GetFirst();
 
437
        wxNode *last  = GetLineControlPoints()->GetLast();
 
438
        *(wxRealPoint *)first->GetData() = from->GetStartPoint();
 
439
        *(wxRealPoint *)last->GetData() = to->GetEndPoint(from->GetKidno());
 
440
 
 
441
        wxRealPoint *p1 = (wxRealPoint *)first->GetNext()->GetData();
 
442
        wxRealPoint *p2 = (wxRealPoint *)last->GetPrevious()->GetData();
 
443
        *p1 = from->GetStartPoint();
 
444
        *p2 = to->GetEndPoint(from->GetKidno());
 
445
        p1->x -= (p1->x - p2->x) / 3. + 8;
 
446
        p2->x += (p1->x - p2->x) / 3. - 8;
 
447
 
 
448
        Initialise();
449
449
}
450
450
 
451
451
 
452
452
#define ARROWWIDTH  4
453
453
 
454
454
 
455
 
void ExplainLine::OnDraw(wxDC& dc)
 
455
void ExplainLine::OnDraw(wxDC &dc)
456
456
{
457
 
    if (m_lineControlPoints)
458
 
    {
459
 
        dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1, wxSOLID));
460
 
        dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(*wxLIGHT_GREY, wxSOLID));
461
 
 
462
 
        wxPoint *points = new wxPoint[11];
463
 
        wxRealPoint *point0 = (wxRealPoint*) m_lineControlPoints->Item(0)->GetData();
464
 
        wxRealPoint *point1 = (wxRealPoint*) m_lineControlPoints->Item(1)->GetData();
465
 
        wxRealPoint *point2 = (wxRealPoint*) m_lineControlPoints->Item(2)->GetData();
466
 
        wxRealPoint *point3 = (wxRealPoint*) m_lineControlPoints->Item(3)->GetData();
467
 
    
468
 
        double phi  = atan2(point2->y - point1->y, point2->x - point1->x);
469
 
        double offs = width * tan(phi/2);
470
 
 
471
 
        points[0].x  = WXROUND(point0->x);
472
 
        points[0].y  = WXROUND(point0->y) - width;
473
 
        points[10].x = WXROUND(point0->x);
474
 
        points[10].y = WXROUND(point0->y) + width;
475
 
 
476
 
        points[1].x  = WXROUND(point1->x + offs);
477
 
        points[1].y  = WXROUND(point1->y) - width;
478
 
        points[9].x  = WXROUND(point1->x - offs);
479
 
        points[9].y  = WXROUND(point1->y) + width;
480
 
 
481
 
        points[2].x  = WXROUND(point2->x + offs);
482
 
        points[2].y  = WXROUND(point2->y) - width;
483
 
        points[8].x  = WXROUND(point2->x - offs);
484
 
        points[8].y  = WXROUND(point2->y) + width;
485
 
 
486
 
        points[3].x  = WXROUND(point3->x) - width - ARROWWIDTH;
487
 
        points[3].y  = WXROUND(point3->y) - width;
488
 
        points[7].x  = WXROUND(point3->x) - width - ARROWWIDTH;
489
 
        points[7].y  = WXROUND(point3->y) + width;
490
 
 
491
 
        points[4].x  = points[3].x;
492
 
        points[4].y  = points[3].y - ARROWWIDTH;
493
 
        points[6].x  = points[7].x;
494
 
        points[6].y  = points[7].y + ARROWWIDTH;
495
 
 
496
 
        points[5].x  = WXROUND(point3->x);
497
 
        points[5].y  = WXROUND(point3->y);
498
 
 
499
 
        dc.DrawPolygon(11, points, 0, 0);
500
 
    }
 
457
        if (m_lineControlPoints)
 
458
        {
 
459
                dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1, wxSOLID));
 
460
                dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(*wxLIGHT_GREY, wxSOLID));
 
461
 
 
462
                wxPoint *points = new wxPoint[11];
 
463
                wxRealPoint *point0 = (wxRealPoint *) m_lineControlPoints->Item(0)->GetData();
 
464
                wxRealPoint *point1 = (wxRealPoint *) m_lineControlPoints->Item(1)->GetData();
 
465
                wxRealPoint *point2 = (wxRealPoint *) m_lineControlPoints->Item(2)->GetData();
 
466
                wxRealPoint *point3 = (wxRealPoint *) m_lineControlPoints->Item(3)->GetData();
 
467
 
 
468
                double phi  = atan2(point2->y - point1->y, point2->x - point1->x);
 
469
                double offs = width * tan(phi / 2);
 
470
 
 
471
                points[0].x  = WXROUND(point0->x);
 
472
                points[0].y  = WXROUND(point0->y) - width;
 
473
                points[10].x = WXROUND(point0->x);
 
474
                points[10].y = WXROUND(point0->y) + width;
 
475
 
 
476
                points[1].x  = WXROUND(point1->x + offs);
 
477
                points[1].y  = WXROUND(point1->y) - width;
 
478
                points[9].x  = WXROUND(point1->x - offs);
 
479
                points[9].y  = WXROUND(point1->y) + width;
 
480
 
 
481
                points[2].x  = WXROUND(point2->x + offs);
 
482
                points[2].y  = WXROUND(point2->y) - width;
 
483
                points[8].x  = WXROUND(point2->x - offs);
 
484
                points[8].y  = WXROUND(point2->y) + width;
 
485
 
 
486
                points[3].x  = WXROUND(point3->x) - width - ARROWWIDTH;
 
487
                points[3].y  = WXROUND(point3->y) - width;
 
488
                points[7].x  = WXROUND(point3->x) - width - ARROWWIDTH;
 
489
                points[7].y  = WXROUND(point3->y) + width;
 
490
 
 
491
                points[4].x  = points[3].x;
 
492
                points[4].y  = points[3].y - ARROWWIDTH;
 
493
                points[6].x  = points[7].x;
 
494
                points[6].y  = points[7].y + ARROWWIDTH;
 
495
 
 
496
                points[5].x  = WXROUND(point3->x);
 
497
                points[5].y  = WXROUND(point3->y);
 
498
 
 
499
                dc.DrawPolygon(11, points, 0, 0);
 
500
        }
501
501
}