PostgreSQL Source Code  git master
scansup.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "mb/pg_wchar.h"
#include "parser/scansup.h"
Include dependency graph for scansup.c:

Go to the source code of this file.

Functions

char * scanstr (const char *s)
 
char * downcase_truncate_identifier (const char *ident, int len, bool warn)
 
char * downcase_identifier (const char *ident, int len, bool warn, bool truncate)
 
void truncate_identifier (char *ident, int len, bool warn)
 
bool scanner_isspace (char ch)
 

Function Documentation

◆ downcase_identifier()

char* downcase_identifier ( const char *  ident,
int  len,
bool  warn,
bool  truncate 
)

Definition at line 139 of file scansup.c.

References i, IS_HIGHBIT_SET, NAMEDATALEN, palloc(), pg_database_encoding_max_length(), and truncate_identifier().

Referenced by downcase_truncate_identifier(), and parse_ident().

140 {
141  char *result;
142  int i;
143  bool enc_is_single_byte;
144 
145  result = palloc(len + 1);
146  enc_is_single_byte = pg_database_encoding_max_length() == 1;
147 
148  /*
149  * SQL99 specifies Unicode-aware case normalization, which we don't yet
150  * have the infrastructure for. Instead we use tolower() to provide a
151  * locale-aware translation. However, there are some locales where this
152  * is not right either (eg, Turkish may do strange things with 'i' and
153  * 'I'). Our current compromise is to use tolower() for characters with
154  * the high bit set, as long as they aren't part of a multi-byte
155  * character, and use an ASCII-only downcasing for 7-bit characters.
156  */
157  for (i = 0; i < len; i++)
158  {
159  unsigned char ch = (unsigned char) ident[i];
160 
161  if (ch >= 'A' && ch <= 'Z')
162  ch += 'a' - 'A';
163  else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch))
164  ch = tolower(ch);
165  result[i] = (char) ch;
166  }
167  result[i] = '\0';
168 
169  if (i >= NAMEDATALEN && truncate)
170  truncate_identifier(result, i, warn);
171 
172  return result;
173 }
#define NAMEDATALEN
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:186
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1106
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
warn
Definition: strftime.c:109
void * palloc(Size size)
Definition: mcxt.c:949
int i

◆ downcase_truncate_identifier()

char* downcase_truncate_identifier ( const char *  ident,
int  len,
bool  warn 
)

Definition at line 130 of file scansup.c.

References downcase_identifier().

Referenced by find_provider(), interval_part(), interval_trunc(), parse_sane_timezone(), SplitIdentifierString(), time_part(), timestamp_part(), timestamp_trunc(), timestamp_zone(), timestamptz_part(), timestamptz_trunc_internal(), timestamptz_trunc_zone(), timestamptz_zone(), timetz_part(), and timetz_zone().

131 {
132  return downcase_identifier(ident, len, warn, true);
133 }
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition: scansup.c:139
warn
Definition: strftime.c:109

◆ scanner_isspace()

bool scanner_isspace ( char  ch)

Definition at line 220 of file scansup.c.

Referenced by parse_ident(), parseNameAndArgTypes(), pgss_store(), SplitDirectoriesString(), SplitGUCList(), and SplitIdentifierString().

221 {
222  /* This must match scan.l's list of {space} characters */
223  if (ch == ' ' ||
224  ch == '\t' ||
225  ch == '\n' ||
226  ch == '\r' ||
227  ch == '\f')
228  return true;
229  return false;
230 }

◆ scanstr()

char* scanstr ( const char *  s)

Definition at line 35 of file scansup.c.

References Assert, i, palloc(), and pstrdup().

36 {
37  char *newStr;
38  int len,
39  i,
40  j;
41 
42  if (s == NULL || s[0] == '\0')
43  return pstrdup("");
44 
45  len = strlen(s);
46 
47  newStr = palloc(len + 1); /* string cannot get longer */
48 
49  for (i = 0, j = 0; i < len; i++)
50  {
51  if (s[i] == '\'')
52  {
53  /*
54  * Note: if scanner is working right, unescaped quotes can only
55  * appear in pairs, so there should be another character.
56  */
57  i++;
58  /* The bootstrap parser is not as smart, so check here. */
59  Assert(s[i] == '\'');
60  newStr[j] = s[i];
61  }
62  else if (s[i] == '\\')
63  {
64  i++;
65  switch (s[i])
66  {
67  case 'b':
68  newStr[j] = '\b';
69  break;
70  case 'f':
71  newStr[j] = '\f';
72  break;
73  case 'n':
74  newStr[j] = '\n';
75  break;
76  case 'r':
77  newStr[j] = '\r';
78  break;
79  case 't':
80  newStr[j] = '\t';
81  break;
82  case '0':
83  case '1':
84  case '2':
85  case '3':
86  case '4':
87  case '5':
88  case '6':
89  case '7':
90  {
91  int k;
92  long octVal = 0;
93 
94  for (k = 0;
95  s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
96  k++)
97  octVal = (octVal << 3) + (s[i + k] - '0');
98  i += k - 1;
99  newStr[j] = ((char) octVal);
100  }
101  break;
102  default:
103  newStr[j] = s[i];
104  break;
105  } /* switch */
106  } /* s[i] == '\\' */
107  else
108  newStr[j] = s[i];
109  j++;
110  }
111  newStr[j] = '\0';
112  return newStr;
113 }
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define Assert(condition)
Definition: c.h:739
void * palloc(Size size)
Definition: mcxt.c:949
int i

◆ truncate_identifier()

void truncate_identifier ( char *  ident,
int  len,
bool  warn 
)

Definition at line 186 of file scansup.c.

References buf, ereport, errcode(), errmsg(), NAMEDATALEN, NOTICE, and pg_mbcliplen().

Referenced by createNewConnection(), deleteConnection(), downcase_identifier(), get_connect_string(), getConnectionByName(), makeArrayTypeName(), parse_and_validate_value(), and SplitIdentifierString().

187 {
188  if (len >= NAMEDATALEN)
189  {
190  len = pg_mbcliplen(ident, len, NAMEDATALEN - 1);
191  if (warn)
192  {
193  /*
194  * We avoid using %.*s here because it can misbehave if the data
195  * is not valid in what libc thinks is the prevailing encoding.
196  */
197  char buf[NAMEDATALEN];
198 
199  memcpy(buf, ident, len);
200  buf[len] = '\0';
201  ereport(NOTICE,
202  (errcode(ERRCODE_NAME_TOO_LONG),
203  errmsg("identifier \"%s\" will be truncated to \"%s\"",
204  ident, buf)));
205  }
206  ident[len] = '\0';
207  }
208 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define NAMEDATALEN
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:862
static char * buf
Definition: pg_test_fsync.c:67
#define ereport(elevel, rest)
Definition: elog.h:141
#define NOTICE
Definition: elog.h:37
warn
Definition: strftime.c:109
int errmsg(const char *fmt,...)
Definition: elog.c:822