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

Commita3aef88

Browse files
committed
Fix incorrect error reporting for duplicate data in \crosstabview.
\crosstabview's complaint about multiple entries for the same crosstabcell quoted the wrong row and/or column values. It would accidentallyappear to work if the data had been in strcmp() order to start with,which probably explains how we missed noticing this during development.This could be fixed in more than one way, but the way I chose was tohang onto both result pointers from bsearch() and use those to get atthe value names.In passing, avoid casting away const in the bsearch comparison functions.No bug there, just poor style.Per bug #14476 from Tomonari Katsumata. Back-patch to 9.6 where\crosstabview was introduced.Report:https://postgr.es/m/20161225021519.10139.45460@wrigleys.postgresql.org
1 parent86d216c commita3aef88

File tree

3 files changed

+48
-24
lines changed

3 files changed

+48
-24
lines changed

‎src/bin/psql/crosstabview.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -352,35 +352,36 @@ printCrosstab(const PGresult *results,
352352
{
353353
introw_number;
354354
intcol_number;
355-
pivot_field*p;
355+
pivot_field*rp,
356+
*cp;
356357
pivot_fieldelt;
357358

358359
/* Find target row */
359360
if (!PQgetisnull(results,rn,field_for_rows))
360361
elt.name=PQgetvalue(results,rn,field_for_rows);
361362
else
362363
elt.name=NULL;
363-
p= (pivot_field*)bsearch(&elt,
364-
piv_rows,
365-
num_rows,
366-
sizeof(pivot_field),
367-
pivotFieldCompare);
368-
Assert(p!=NULL);
369-
row_number=p->rank;
364+
rp= (pivot_field*)bsearch(&elt,
365+
piv_rows,
366+
num_rows,
367+
sizeof(pivot_field),
368+
pivotFieldCompare);
369+
Assert(rp!=NULL);
370+
row_number=rp->rank;
370371

371372
/* Find target column */
372373
if (!PQgetisnull(results,rn,field_for_columns))
373374
elt.name=PQgetvalue(results,rn,field_for_columns);
374375
else
375376
elt.name=NULL;
376377

377-
p= (pivot_field*)bsearch(&elt,
378-
piv_columns,
379-
num_columns,
380-
sizeof(pivot_field),
381-
pivotFieldCompare);
382-
Assert(p!=NULL);
383-
col_number=p->rank;
378+
cp= (pivot_field*)bsearch(&elt,
379+
piv_columns,
380+
num_columns,
381+
sizeof(pivot_field),
382+
pivotFieldCompare);
383+
Assert(cp!=NULL);
384+
col_number=cp->rank;
384385

385386
/* Place value into cell */
386387
if (col_number >=0&&row_number >=0)
@@ -396,10 +397,10 @@ printCrosstab(const PGresult *results,
396397
if (cont.cells[idx]!=NULL)
397398
{
398399
psql_error("\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"\n",
399-
piv_rows[row_number].name ?piv_rows[row_number].name :
400-
popt.nullPrint ?popt.nullPrint :"(null)",
401-
piv_columns[col_number].name ?piv_columns[col_number].name :
402-
popt.nullPrint ?popt.nullPrint :"(null)");
400+
rp->name ?rp->name :
401+
(popt.nullPrint ?popt.nullPrint :"(null)"),
402+
cp->name ?cp->name :
403+
(popt.nullPrint ?popt.nullPrint :"(null)"));
403404
gotoerror;
404405
}
405406

@@ -694,8 +695,8 @@ indexOfColumn(char *arg, const PGresult *res)
694695
staticint
695696
pivotFieldCompare(constvoid*a,constvoid*b)
696697
{
697-
pivot_field*pa= (pivot_field*)a;
698-
pivot_field*pb= (pivot_field*)b;
698+
constpivot_field*pa= (constpivot_field*)a;
699+
constpivot_field*pb= (constpivot_field*)b;
699700

700701
/* test null values */
701702
if (!pb->name)
@@ -704,12 +705,11 @@ pivotFieldCompare(const void *a, const void *b)
704705
return1;
705706

706707
/* non-null values */
707-
returnstrcmp(((pivot_field*)a)->name,
708-
((pivot_field*)b)->name);
708+
returnstrcmp(pa->name,pb->name);
709709
}
710710

711711
staticint
712712
rankCompare(constvoid*a,constvoid*b)
713713
{
714-
return*((int*)a)-*((int*)b);
714+
return*((constint*)a)-*((constint*)b);
715715
}

‎src/test/regress/expected/psql_crosstab.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,16 @@ SELECT a,a,1 FROM generate_series(1,3000) AS a
201201
SELECT 1 \crosstabview
202202
\crosstabview: query must return at least three columns
203203
DROP TABLE ctv_data;
204+
-- check error reporting (bug #14476)
205+
CREATE TABLE ctv_data (x int, y int, v text);
206+
INSERT INTO ctv_data SELECT 1, x, '*' || x FROM generate_series(1,10) x;
207+
SELECT * FROM ctv_data \crosstabview
208+
x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
209+
---+----+----+----+----+----+----+----+----+----+-----
210+
1 | *1 | *2 | *3 | *4 | *5 | *6 | *7 | *8 | *9 | *10
211+
(1 row)
212+
213+
INSERT INTO ctv_data VALUES (1, 10, '*'); -- duplicate data to cause error
214+
SELECT * FROM ctv_data \crosstabview
215+
\crosstabview: query result contains multiple data values for row "1", column "10"
216+
DROP TABLE ctv_data;

‎src/test/regress/sql/psql_crosstab.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,14 @@ SELECT a,a,1 FROM generate_series(1,3000) AS a
111111
SELECT1 \crosstabview
112112

113113
DROPTABLE ctv_data;
114+
115+
-- check error reporting (bug #14476)
116+
CREATETABLEctv_data (xint, yint, vtext);
117+
118+
INSERT INTO ctv_dataSELECT1, x,'*'|| xFROM generate_series(1,10) x;
119+
SELECT*FROM ctv_data \crosstabview
120+
121+
INSERT INTO ctv_dataVALUES (1,10,'*');-- duplicate data to cause error
122+
SELECT*FROM ctv_data \crosstabview
123+
124+
DROPTABLE ctv_data;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp