3
( \                 @   s   d dl mZ d dlZd dlZd dlmZ d dlmZmZ ej	dej	dej	dej	dd	Z
dddZdddZej	dZdd Zdd Zdd ZdS )    )print_functionN)
Identifier)TokenErrorz(\w+)$z([^():,\s]+)$z([^\.():,\s]+)$z	([^\s]+)$)alphanum_underscoreZmany_punctuationsZmost_punctuationsZall_punctuationsr   c             C   s@   | sdS | d j  rdS t| }|j| }|r8|jdS dS dS )a  
    Find the last word in a sentence.

    >>> last_word('abc')
    'abc'
    >>> last_word(' abc')
    'abc'
    >>> last_word('')
    ''
    >>> last_word(' ')
    ''
    >>> last_word('abc ')
    ''
    >>> last_word('abc def')
    'def'
    >>> last_word('abc def ')
    ''
    >>> last_word('abc def;')
    ''
    >>> last_word('bac $def')
    'def'
    >>> last_word('bac $def', include='most_punctuations')
    '$def'
    >>> last_word('bac \def', include='most_punctuations')
    '\\\\def'
    >>> last_word('bac \def;', include='most_punctuations')
    '\\\\def;'
    >>> last_word('bac::def', include='most_punctuations')
    'def'
    >>> last_word('"foo*bar', include='most_punctuations')
    '"foo*bar'
        r   N)isspacecleanup_regexsearchgroup)textincludeZregexZmatches r   I/usr/share/pgadmin4/web/pgadmin/utils/sqlautocomplete/parseutils/utils.py	last_word   s    "

r   c             C   s   | j  sdS tj| d }t|j }|dt||  }d}x`t|D ]T}|jdksj|jrH|jj	 |krH|j
|}djd	d
 |d|d  D }||fS qHW dS )z Find the last sql keyword in an SQL statement

    Returns the value of the last keyword, and the text of the query with
    everything after the last keyword stripped
    Nr   r   ANDORNOTBETWEEN(c             s   s   | ]}|j V  qd S )N)value).0tokr   r   r   	<genexpr>a   s    z$find_prev_keyword.<locals>.<genexpr>r   )Nr   )r   r   r   r   )Nr   )stripsqlparseparselistflattenlenreversedr   Z
is_keywordupperindexjoin)sqlZn_skipparsedZ	flattenedZlogical_operatorstidxr   r   r   r   find_prev_keywordC   s    
 r*   z^\$[^$]*\$$c             C   s   t j| }tdd |D S )z4Returns true if the query contains an unclosed quotec             s   s   | ]}t |V  qd S )N)_parsed_is_open_quote)r   pr   r   r   r   p   s    z is_open_quote.<locals>.<genexpr>)r   r   any)r&   r'   r   r   r   is_open_quotek   s    
r.   c             C   s   t dd | j D S )Nc             s   s   | ]}|j tjdV  qdS )'$N)r/   r0   )matchr   r   )r   r   r   r   r   r   u   s    z(_parsed_is_open_quote.<locals>.<genexpr>)r-   r    )r'   r   r   r   r+   s   s    r+   c             C   sb   t j| d }t|j}|dkr:t|jd tr:|jd S |jtdfdd rZt| d S dS dS )as  Attempt to parse a (partially typed) word as an identifier

    word may include a schema qualification, like `schema_name.partial_name`
    or `schema_name.` There may also be unclosed quotation marks, like
    `"schema`, or `schema."partial_name`

    :param word: string representing a (partially complete) identifier
    :return: sqlparse.sql.Identifier, or None
    r   r   ")mN)	r   r   r!   tokens
isinstancer   Ztoken_next_byr   parse_partial_identifier)Zwordr,   Zn_tokr   r   r   r6   x   s    

r6   )r   )r   )Z
__future__r   rer   Zsqlparse.sqlr   Zsqlparse.tokensr   r   compiler   r   r*   Zdollar_quote_regexr.   r+   r6   r   r   r   r   <module>   s   
0
%
