PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
scansup.h File Reference
This graph shows which files directly or indirectly include this file:

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

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

Definition at line 140 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().

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

Definition at line 131 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(), timestamptz_zone(), timetz_part(), and timetz_zone().

132 {
133  return downcase_identifier(ident, len, warn, true);
134 }
char * downcase_identifier(const char *ident, int len, bool warn, bool truncate)
Definition: scansup.c:140
static void warn(void)
bool scanner_isspace ( char  ch)

Definition at line 221 of file scansup.c.

Referenced by pgss_store().

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

Definition at line 36 of file scansup.c.

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

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

Definition at line 187 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().

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