Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

scansup.c File Reference

#include "postgres.h"
#include <ctype.h>
#include "parser/scansup.h"
#include "mb/pg_wchar.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)
void truncate_identifier (char *ident, int len, bool warn)
bool scanner_isspace (char ch)

Function Documentation

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

Definition at line 131 of file scansup.c.

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

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

{
    char       *result;
    int         i;

    result = palloc(len + 1);

    /*
     * SQL99 specifies Unicode-aware case normalization, which we don't yet
     * have the infrastructure for.  Instead we use tolower() to provide a
     * locale-aware translation.  However, there are some locales where this
     * is not right either (eg, Turkish may do strange things with 'i' and
     * 'I').  Our current compromise is to use tolower() for characters with
     * the high bit set, and use an ASCII-only downcasing for 7-bit
     * characters.
     */
    for (i = 0; i < len; i++)
    {
        unsigned char ch = (unsigned char) ident[i];

        if (ch >= 'A' && ch <= 'Z')
            ch += 'a' - 'A';
        else if (IS_HIGHBIT_SET(ch) && isupper(ch))
            ch = tolower(ch);
        result[i] = (char) ch;
    }
    result[i] = '\0';

    if (i >= NAMEDATALEN)
        truncate_identifier(result, i, warn);

    return result;
}

bool scanner_isspace ( char  ch  ) 

Definition at line 209 of file scansup.c.

{
    /* This must match scan.l's list of {space} characters */
    if (ch == ' ' ||
        ch == '\t' ||
        ch == '\n' ||
        ch == '\r' ||
        ch == '\f')
        return true;
    return false;
}

char* scanstr ( const char *  s  ) 

Definition at line 36 of file scansup.c.

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

{
    char       *newStr;
    int         len,
                i,
                j;

    if (s == NULL || s[0] == '\0')
        return pstrdup("");

    len = strlen(s);

    newStr = palloc(len + 1);   /* string cannot get longer */

    for (i = 0, j = 0; i < len; i++)
    {
        if (s[i] == '\'')
        {
            /*
             * Note: if scanner is working right, unescaped quotes can only
             * appear in pairs, so there should be another character.
             */
            i++;
            /* The bootstrap parser is not as smart, so check here. */
            Assert(s[i] == '\'');
            newStr[j] = s[i];
        }
        else if (s[i] == '\\')
        {
            i++;
            switch (s[i])
            {
                case 'b':
                    newStr[j] = '\b';
                    break;
                case 'f':
                    newStr[j] = '\f';
                    break;
                case 'n':
                    newStr[j] = '\n';
                    break;
                case 'r':
                    newStr[j] = '\r';
                    break;
                case 't':
                    newStr[j] = '\t';
                    break;
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                    {
                        int         k;
                        long        octVal = 0;

                        for (k = 0;
                             s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
                             k++)
                            octVal = (octVal << 3) + (s[i + k] - '0');
                        i += k - 1;
                        newStr[j] = ((char) octVal);
                    }
                    break;
                default:
                    newStr[j] = s[i];
                    break;
            }                   /* switch */
        }                       /* s[i] == '\\' */
        else
            newStr[j] = s[i];
        j++;
    }
    newStr[j] = '\0';
    return newStr;
}

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

Definition at line 175 of file scansup.c.

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

Referenced by createNewConnection(), deleteConnection(), downcase_truncate_identifier(), get_connect_string(), getConnectionByName(), makeArrayTypeName(), set_config_option(), and SplitIdentifierString().

{
    if (len >= NAMEDATALEN)
    {
        len = pg_mbcliplen(ident, len, NAMEDATALEN - 1);
        if (warn)
        {
            /*
             * We avoid using %.*s here because it can misbehave if the data
             * is not valid in what libc thinks is the prevailing encoding.
             */
            char        buf[NAMEDATALEN];

            memcpy(buf, ident, len);
            buf[len] = '\0';
            ereport(NOTICE,
                    (errcode(ERRCODE_NAME_TOO_LONG),
                     errmsg("identifier \"%s\" will be truncated to \"%s\"",
                            ident, buf)));
        }
        ident[len] = '\0';
    }
}