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

Commitfa09ee6

Browse files
committed
Document the always-true-but-previously-undocumented fact that PQfnumber()
will downcase the supplied field name unless it is double-quoted. Also,upgrade the routine's handling of double quotes to match the backend,in particular support doubled double quotes within quoted identifiers.Per pgsql-interfaces discussion a couple weeks ago.
1 parentb833c3d commitfa09ee6

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.138 2003/10/03 18:26:14 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.139 2003/10/04 21:05:20 tgl Exp $
33
-->
44

55
<chapter id="libpq">
@@ -1553,8 +1553,7 @@ NULL is returned if the column number is out of range.
15531553
<term><function>PQfnumber</function><indexterm><primary>PQfnumber</></></term>
15541554
<listitem>
15551555
<para>
1556-
Returns the column number
1557-
associated with the given column name.
1556+
Returns the column number associated with the given column name.
15581557
<synopsis>
15591558
int PQfnumber(const PGresult *res,
15601559
const char *column_name);
@@ -1564,6 +1563,24 @@ int PQfnumber(const PGresult *res,
15641563
<para>
15651564
-1 is returned if the given name does not match any column.
15661565
</para>
1566+
1567+
<para>
1568+
The given name is treated like an identifier in an SQL command,
1569+
that is, it is downcased unless double-quoted. For example,
1570+
given a query result generated from the SQL command
1571+
<programlisting>
1572+
select 1 as FOO, 2 as "BAR";
1573+
</programlisting>
1574+
we would have the results:
1575+
<programlisting>
1576+
PQfname(res, 0) <lineannotation>foo</lineannotation>
1577+
PQfname(res, 1) <lineannotation>BAR</lineannotation>
1578+
PQfnumber(res, "FOO") <lineannotation>0</lineannotation>
1579+
PQfnumber(res, "foo") <lineannotation>0</lineannotation>
1580+
PQfnumber(res, "BAR") <lineannotation>-1</lineannotation>
1581+
PQfnumber(res, "\"BAR\"") <lineannotation>1</lineannotation>
1582+
</programlisting>
1583+
</para>
15671584
</listitem>
15681585
</varlistentry>
15691586

‎src/interfaces/libpq/fe-exec.c

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.150 2003/10/03 18:26:14 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.151 2003/10/04 21:05:21 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1803,32 +1803,80 @@ PQfname(const PGresult *res, int field_num)
18031803
}
18041804

18051805
/*
1806-
* returns -1 on a bad field name
1806+
* PQfnumber: find column number given column name
1807+
*
1808+
* The column name is parsed as if it were in a SQL statement, including
1809+
* case-folding and double-quote processing. But note a possible gotcha:
1810+
* downcasing in the frontend might follow different locale rules than
1811+
* downcasing in the backend...
1812+
*
1813+
* Returns -1 if no match. In the present backend it is also possible
1814+
* to have multiple matches, in which case the first one is found.
18071815
*/
18081816
int
18091817
PQfnumber(constPGresult*res,constchar*field_name)
18101818
{
1811-
inti;
18121819
char*field_case;
1820+
boolin_quotes;
1821+
char*iptr;
1822+
char*optr;
1823+
inti;
18131824

18141825
if (!res)
18151826
return-1;
18161827

1828+
/*
1829+
* Note: it is correct to reject a zero-length input string; the proper
1830+
* input to match a zero-length field name would be "".
1831+
*/
18171832
if (field_name==NULL||
18181833
field_name[0]=='\0'||
18191834
res->attDescs==NULL)
18201835
return-1;
18211836

1837+
/*
1838+
* Note: this code will not reject partially quoted strings, eg
1839+
* foo"BAR"foo will become fooBARfoo when it probably ought to be
1840+
* an error condition.
1841+
*/
18221842
field_case=strdup(field_name);
1823-
if (*field_case=='"')
1843+
if (field_case==NULL)
1844+
return-1;/* grotty */
1845+
1846+
in_quotes= false;
1847+
optr=field_case;
1848+
for (iptr=field_case;*iptr;iptr++)
18241849
{
1825-
strcpy(field_case,field_case+1);
1826-
*(field_case+strlen(field_case)-1)='\0';
1850+
charc=*iptr;
1851+
1852+
if (in_quotes)
1853+
{
1854+
if (c=='"')
1855+
{
1856+
if (iptr[1]=='"')
1857+
{
1858+
/* doubled quotes become a single quote */
1859+
*optr++='"';
1860+
iptr++;
1861+
}
1862+
else
1863+
in_quotes= false;
1864+
}
1865+
else
1866+
*optr++=c;
1867+
}
1868+
elseif (c=='"')
1869+
{
1870+
in_quotes= true;
1871+
}
1872+
else
1873+
{
1874+
if (isupper((unsignedchar)c))
1875+
c=tolower((unsignedchar)c);
1876+
*optr++=c;
1877+
}
18271878
}
1828-
else
1829-
for (i=0;field_case[i];i++)
1830-
if (isupper((unsignedchar)field_case[i]))
1831-
field_case[i]=tolower((unsignedchar)field_case[i]);
1879+
*optr='\0';
18321880

18331881
for (i=0;i<res->numAttributes;i++)
18341882
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp