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

Commit9603a32

Browse files
committed
Avoid code duplication in \crosstabview.
In commit6f0d6a5 I added a duplicate copy of psqlscanslash's identifierdowncasing code, but actually it's not hard to split that out as a callablesubroutine and avoid the duplication.
1 parent4039c73 commit9603a32

File tree

3 files changed

+56
-60
lines changed

3 files changed

+56
-60
lines changed

‎src/bin/psql/crosstabview.c

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include"common.h"
1313
#include"crosstabview.h"
1414
#include"pqexpbuffer.h"
15+
#include"psqlscanslash.h"
1516
#include"settings.h"
1617

1718

@@ -648,39 +649,14 @@ indexOfColumn(char *arg, const PGresult *res)
648649
}
649650
else
650651
{
651-
boolinquotes= false;
652-
char*cp=arg;
653652
inti;
654653

655654
/*
656655
* Dequote and downcase the column name. By checking for all-digits
657656
* before doing this, we can ensure that a quoted name is treated as a
658-
* name even if it's all digits. This transformation should match
659-
* what psqlscanslash.l does in OT_SQLID mode. (XXX ideally we would
660-
* let the lexer do this, but then we couldn't tell if the name was
661-
* quoted.)
657+
* name even if it's all digits.
662658
*/
663-
while (*cp)
664-
{
665-
if (*cp=='"')
666-
{
667-
if (inquotes&&cp[1]=='"')
668-
{
669-
/* Keep the first quote, remove the second */
670-
cp++;
671-
}
672-
inquotes= !inquotes;
673-
/* Collapse out quote at *cp */
674-
memmove(cp,cp+1,strlen(cp));
675-
/* do not advance cp */
676-
}
677-
else
678-
{
679-
if (!inquotes)
680-
*cp=pg_tolower((unsignedchar)*cp);
681-
cp+=PQmblen(cp,pset.encoding);
682-
}
683-
}
659+
dequote_downcase_identifier(arg, true,pset.encoding);
684660

685661
/* Now look for match(es) among res' column names */
686662
idx=-1;

‎src/bin/psql/psqlscanslash.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ extern char *psql_scan_slash_option(PsqlScanState state,
3232

3333
externvoidpsql_scan_slash_command_end(PsqlScanStatestate);
3434

35+
externvoiddequote_downcase_identifier(char*str,booldowncase,intencoding);
36+
3537
#endif/* PSQLSCANSLASH_H */

‎src/bin/psql/psqlscanslash.l

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -566,42 +566,15 @@ psql_scan_slash_option(PsqlScanState state,
566566

567567
/*
568568
* If SQL identifier processing was requested, then we strip out
569-
* excess double quotes and downcase unquoted letters.
570-
* Doubled double-quotes become output double-quotes, per spec.
571-
*
572-
* Note that a string like FOO"BAR"BAZ will be converted to
573-
* fooBARbaz; this is somewhat inconsistent with the SQL spec,
574-
* which would have us parse it as several identifiers. But
575-
* for psql's purposes, we want a string like "foo"."bar" to
576-
* be treated as one option, so there's little choice.
569+
* excess double quotes and optionally downcase unquoted letters.
577570
*/
578571
if (type == OT_SQLID || type == OT_SQLIDHACK)
579572
{
580-
boolinquotes =false;
581-
char *cp = mybuf.data;
582-
583-
while (*cp)
584-
{
585-
if (*cp =='"')
586-
{
587-
if (inquotes && cp[1] =='"')
588-
{
589-
/* Keep the first quote, remove the second */
590-
cp++;
591-
}
592-
inquotes = !inquotes;
593-
/* Collapse out quote at *cp */
594-
memmove(cp, cp +1,strlen(cp));
595-
mybuf.len--;
596-
/* do not advance cp */
597-
}
598-
else
599-
{
600-
if (!inquotes && type == OT_SQLID)
601-
*cp =pg_tolower((unsignedchar) *cp);
602-
cp +=PQmblen(cp, state->encoding);
603-
}
604-
}
573+
dequote_downcase_identifier(mybuf.data,
574+
(type != OT_SQLIDHACK),
575+
state->encoding);
576+
/* update mybuf.len for possible shortening */
577+
mybuf.len =strlen(mybuf.data);
605578
}
606579
break;
607580
case xslashquote:
@@ -667,6 +640,51 @@ psql_scan_slash_command_end(PsqlScanState state)
667640
psql_scan_reselect_sql_lexer(state);
668641
}
669642

643+
/*
644+
* De-quote and optionally downcase a SQL identifier.
645+
*
646+
* The string at *str is modified in-place; it can become shorter,
647+
* but not longer.
648+
*
649+
* If downcase is true then non-quoted letters are folded to lower case.
650+
* Ideally this behavior will match the backend's downcase_identifier();
651+
* but note that it could differ if LC_CTYPE is different in the frontend.
652+
*
653+
* Note that a string like FOO"BAR"BAZ will be converted to fooBARbaz;
654+
* this is somewhat inconsistent with the SQL spec, which would have us
655+
* parse it as several identifiers. But for psql's purposes, we want a
656+
* string like "foo"."bar" to be treated as one option, so there's little
657+
* choice; this routine doesn't get to change the token boundaries.
658+
*/
659+
void
660+
dequote_downcase_identifier(char *str,bool downcase,int encoding)
661+
{
662+
boolinquotes =false;
663+
char *cp = str;
664+
665+
while (*cp)
666+
{
667+
if (*cp =='"')
668+
{
669+
if (inquotes && cp[1] =='"')
670+
{
671+
/* Keep the first quote, remove the second */
672+
cp++;
673+
}
674+
inquotes = !inquotes;
675+
/* Collapse out quote at *cp */
676+
memmove(cp, cp +1,strlen(cp));
677+
/* do not advance cp */
678+
}
679+
else
680+
{
681+
if (downcase && !inquotes)
682+
*cp =pg_tolower((unsignedchar) *cp);
683+
cp +=PQmblen(cp, encoding);
684+
}
685+
}
686+
}
687+
670688
/*
671689
* Evaluate a backticked substring of a slash command's argument.
672690
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp