LCOV - code coverage report
Current view: top level - src/common - keywords.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 21 21 100.0 %
Date: 2017-09-29 13:40:31 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * keywords.c
       4             :  *    lexical token lookup for key words in PostgreSQL
       5             :  *
       6             :  *
       7             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  *
      11             :  * IDENTIFICATION
      12             :  *    src/common/keywords.c
      13             :  *
      14             :  *-------------------------------------------------------------------------
      15             :  */
      16             : #ifndef FRONTEND
      17             : #include "postgres.h"
      18             : #else
      19             : #include "postgres_fe.h"
      20             : #endif
      21             : 
      22             : #ifndef FRONTEND
      23             : 
      24             : #include "parser/gramparse.h"
      25             : 
      26             : #define PG_KEYWORD(a,b,c) {a,b,c},
      27             : 
      28             : #else
      29             : 
      30             : #include "common/keywords.h"
      31             : 
      32             : /*
      33             :  * We don't need the token number for frontend uses, so leave it out to avoid
      34             :  * requiring backend headers that won't compile cleanly here.
      35             :  */
      36             : #define PG_KEYWORD(a,b,c) {a,0,c},
      37             : 
      38             : #endif                          /* FRONTEND */
      39             : 
      40             : 
      41             : const ScanKeyword ScanKeywords[] = {
      42             : #include "parser/kwlist.h"
      43             : };
      44             : 
      45             : const int   NumScanKeywords = lengthof(ScanKeywords);
      46             : 
      47             : 
      48             : /*
      49             :  * ScanKeywordLookup - see if a given word is a keyword
      50             :  *
      51             :  * The table to be searched is passed explicitly, so that this can be used
      52             :  * to search keyword lists other than the standard list appearing above.
      53             :  *
      54             :  * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
      55             :  *
      56             :  * The match is done case-insensitively.  Note that we deliberately use a
      57             :  * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
      58             :  * even if we are in a locale where tolower() would produce more or different
      59             :  * translations.  This is to conform to the SQL99 spec, which says that
      60             :  * keywords are to be matched in this way even though non-keyword identifiers
      61             :  * receive a different case-normalization mapping.
      62             :  */
      63             : const ScanKeyword *
      64      390165 : ScanKeywordLookup(const char *text,
      65             :                   const ScanKeyword *keywords,
      66             :                   int num_keywords)
      67             : {
      68             :     int         len,
      69             :                 i;
      70             :     char        word[NAMEDATALEN];
      71             :     const ScanKeyword *low;
      72             :     const ScanKeyword *high;
      73             : 
      74      390165 :     len = strlen(text);
      75             :     /* We assume all keywords are shorter than NAMEDATALEN. */
      76      390165 :     if (len >= NAMEDATALEN)
      77           2 :         return NULL;
      78             : 
      79             :     /*
      80             :      * Apply an ASCII-only downcasing.  We must not use tolower() since it may
      81             :      * produce the wrong translation in some locales (eg, Turkish).
      82             :      */
      83     2677366 :     for (i = 0; i < len; i++)
      84             :     {
      85     2287203 :         char        ch = text[i];
      86             : 
      87     2287203 :         if (ch >= 'A' && ch <= 'Z')
      88      569410 :             ch += 'a' - 'A';
      89     2287203 :         word[i] = ch;
      90             :     }
      91      390163 :     word[len] = '\0';
      92             : 
      93             :     /*
      94             :      * Now do a binary search using plain strcmp() comparison.
      95             :      */
      96      390163 :     low = keywords;
      97      390163 :     high = keywords + (num_keywords - 1);
      98     3809399 :     while (low <= high)
      99             :     {
     100             :         const ScanKeyword *middle;
     101             :         int         difference;
     102             : 
     103     3203216 :         middle = low + (high - low) / 2;
     104     3203216 :         difference = strcmp(middle->name, word);
     105     3203216 :         if (difference == 0)
     106      174143 :             return middle;
     107     3029073 :         else if (difference < 0)
     108     1397055 :             low = middle + 1;
     109             :         else
     110     1632018 :             high = middle - 1;
     111             :     }
     112             : 
     113      216020 :     return NULL;
     114             : }

Generated by: LCOV version 1.11