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

Appearance settings

Commit 9603a32

Browse filesBrowse files
committed
Avoid code duplication in \crosstabview.
In commit 6f0d6a5 I added a duplicate copy of psqlscanslash's identifier downcasing code, but actually it's not hard to split that out as a callable subroutine and avoid the duplication.
1 parent 4039c73 commit 9603a32
Copy full SHA for 9603a32

File tree

Expand file treeCollapse file tree

3 files changed

+56
-60
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+56
-60
lines changed

‎src/bin/psql/crosstabview.c

Copy file name to clipboardExpand all lines: src/bin/psql/crosstabview.c
+3-27Lines 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-
bool inquotes = false;
652-
char *cp = arg;
653652
int i;
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((unsigned char) *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

Copy file name to clipboardExpand all lines: src/bin/psql/psqlscanslash.h
+2Lines 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
extern void psql_scan_slash_command_end(PsqlScanState state);
3434

35+
extern void dequote_downcase_identifier(char *str, bool downcase, int encoding);
36+
3537
#endif /* PSQLSCANSLASH_H */

‎src/bin/psql/psqlscanslash.l

Copy file name to clipboardExpand all lines: src/bin/psql/psqlscanslash.l
+51-33Lines 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-
bool inquotes = 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((unsigned char) *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+
bool inquotes = 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((unsigned char) *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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.