3
dT                 @   s  d Z ddlmZ ddlZddlZddlZddlmZ ddlmZm	Z	m
Z
mZ ddlmZmZ ddlmZmZ ddlmZmZmZ dd	lmZmZmZmZmZ dd
lmZ dd Zdd Z dd Z!dd Z"dd Z#dd Z$dmddZ%dd Z&dd Z'dd Z(dd  Z)d!d" Z*dnd#d$Z+d%d& Z,d'd( Z-d)d* Z.d+d, Z/d-d. Z0d/d0 Z1d1d2 Z2d3d4 Z3d5d6 Z4d7d8 Z5d9d: Z6G d;d< d<e7Z8d=d> d=d> fd?d@Z9dAd> fdBdCZ:dDd> dEd> dfdFdGZ;dHdI Z<dJdK Z=dLdM Z>dNdO Z?dodPdQZ@dRdS ZAdTdU ZBdVdW ZCdXdY ZDdZd[ Zd\d] ZEdpd^d_ZFd`da ZGdbdc ZHdqdddeZIdrdfdgZJdhdi ZKeLdjkrddlMZMddklNmOZO ddlPZQeQjRjSeMjTdl reUeMjTdl ZVn
eMjTdl ZVeOjWeVZXeYeX eJeXZZeKeZ dS )sz
Converting the 'parse-tree' output of pyparsing to a SPARQL Algebra expression

http://www.w3.org/TR/sparql11-query/#sparqlQuery

    )print_functionN)reduce)LiteralVariableURIRefBNode)PrologueQuery)	CompValueExpr)and_
TrueFiltersimplify)InvPathAlternativePathSequencePathMulPathNegatedPath)ParseResultsc             C   s   t d| |dS )NOrderBy)pexpr)r
   )r   r    r   ?/tmp/pip-build-7vycvbft/rdflib/rdflib/plugins/sparql/algebra.pyr      s    r   c             C   s   t d| dS )N
ToMultiSet)r   )r
   )r   r   r   r   r   #   s    r   c             C   s   t d| |dS )NUnion)p1p2)r
   )r   r   r   r   r   r   '   s    r   c             C   s   t d| |dS )NJoin)r   r   )r
   )r   r   r   r   r   r   +   s    r   c             C   s   t d| |dS )NMinus)r   r   )r
   )r   r   r   r   r   r   /   s    r   c             C   s   t d| |dS )NGraph)termr   )r
   )r!   graphr   r   r   r    3   s    r    c             C   s   t d| p
g dS )NBGP)triples)r
   )r$   r   r   r   r#   7   s    r#   c             C   s   t d| ||dS )NLeftJoin)r   r   r   )r
   )r   r   r   r   r   r   r%   ;   s    r%   c             C   s   t d| |dS )NFilter)r   r   )r
   )r   r   r   r   r   r&   ?   s    r&   c             C   s   t d| ||dS )NExtend)r   r   var)r
   )r   r   r(   r   r   r   r'   C   s    r'   c             C   s   t d| dS )Nvalues)res)r
   )r*   r   r   r   ValuesG   s    r+   c             C   s   t d| |dS )NProject)r   PV)r
   )r   r-   r   r   r   r,   K   s    r,   c             C   s   t d| |dS )NGroup)r   r   )r
   )r   r   r   r   r   r.   O   s    r.   c                s<   t fdd| D t fdd| D  t| d t fS )Nc                s&   g | ]}| krt |ttfr|qS r   )
isinstancer   r   ).0x)	varsknownr   r   
<listcomp>T   s    
z_knownTerms.<locals>.<listcomp>c             3   s   | ]} j |d V  qdS )r   N)get)r0   r1   )	varscountr   r   	<genexpr>V   s    z_knownTerms.<locals>.<genexpr>   )lensumr/   r   )Ztripler2   r5   r   )r5   r2   r   _knownTermsS   s    r:   c                s*  dd }dd | D } t  tjt x<| D ]4}x.|d D ]"}t|ttfr: |  d7  < q:W q,W d}x|t| k rt fdd| |d	 D | |d	< | | d d }d}xZ|| t| k o| ||  d d |krx"| ||  d D ]}|| qW |d7 }qW |d7 }qjW d
d | D S )zZ
    Reorder triple patterns so that we execute the
    ones with most bindings first
    c             S   s   t | ttfr|j|  d S )N)r/   r   r   add)r!   r2   r   r   r   _addvara   s    zreorderTriples.<locals>._addvarc             S   s   g | ]}d |fqS )Nr   )r0   r1   r   r   r   r3   e   s    z"reorderTriples.<locals>.<listcomp>   r   c             3   s&   | ]}t |d   |d  fV  qdS )r=   N)r:   )r0   r1   )r5   r2   r   r   r6   v   s   z!reorderTriples.<locals>.<genexpr>Nc             S   s   g | ]}|d  qS )r=   r   )r0   r1   r   r   r   r3      s    )	setcollectionsdefaultdictintr/   r   r   r8   sorted)lr<   tcijr   )r5   r2   r   reorderTriples[   s(    

	,rH   c                sH   t dd   t d dkr&tdt fddtdt dD S )Nc             S   s   | | S )Nr   )r1   yr   r   r   <lambda>   s    ztriples.<locals>.<lambda>   r   zthese aint triplesc             3   s,   | ]$} |  |d    |d  fV  qdS )r=   r7   Nr   )r0   r1   )rC   r   r   r6      s   ztriples.<locals>.<genexpr>)r   r8   	ExceptionrH   range)rC   r   )rC   r   r$      s
    r$   c             C   s\   t | trD| jdkr|j| S | jdkrXt| j| j|j| jdS nt | trX|j| S dS )z'
    Expand prefixed/relative URIs
    Zpnameliteral)langdatatypeN)	r/   r
   name
absolutizer   stringrO   rP   r   )r   prologuer   r   r   translatePName   s    





rU   c             C   sD  t | tr@| jdkr<t| jdkr.| jd S t| j S n| jdkrjt| jdkr^| jd S t| j S n| jdkr| js| jS t | jtrt| jdkrt	dt
| jd | jS t
| j| jS n|| jdkrt | jtrt| jdkrt	dt| jd S t| jS n2| jdkr@t | jtr6tt| j S t| jS d	S )
z,
    Translate PropertyPath expressions
    ZPathAlternativer=   r   ZPathSequenceZPathEltzDenkfehler!ZPathEltOrInverseZPathNegatedPropertySetN)r/   r
   rQ   r8   partr   r   modlistrL   r   r   r   )r   r   r   r   translatePath   s6    




rY   c             C   s   dd }t | |d} | S )z
    Translate the graph pattern used by EXISTS and NOT EXISTS
    http://www.w3.org/TR/sparql11-query/#sparqlCollectFilters
    c             S   s8   t | tr4| jdkr4t| j| _| jjdkr4d| j_d S )NBuiltin_EXISTSBuiltin_NOTEXISTSr&   T)rZ   r[   )r/   r
   rQ   translateGroupGraphPatternr"   Zno_isolated_scope)nr   r   r   _c   s
    

ztranslateExists.<locals>._c)	visitPost)traverse)er^   r   r   r   translateExists   s    rb   c             C   s`   g }d}xF|t | k rN| | }|jdkrD|jt|j | j| q
|d7 }q
W |r\t| S dS )z

    FILTER expressions apply to the whole group graph pattern in which
    they appear.

    http://www.w3.org/TR/sparql11-query/#sparqlCollectFilters
    r   r&   r=   N)r8   rQ   appendrb   r   popr   )partsfiltersrF   r   r   r   r   collectAndRemoveFilters   s    	
rg   c             C   s4   d }x*| j D ] }t|}|s"|}qt||}qW |S )N)r"   r\   r   )graphPatternAgr   r   r   !translateGroupOrUnionGraphPattern   s    rk   c             C   s   t | jt| jS )N)r    r!   r\   r"   )rh   r   r   r   translateGraphGraphPattern   s    rl   c             C   s   t t| S )N)r   translateValues)rh   r   r   r   translateInlineData  s    rn   c             C   s  | j dkrtt| d S | js&g | _t| j}g }x\| jD ]R}|j dkr|oZ|d j dksh|jt  |d d  t|j7  < q<|j| q<W t }x.|D ]$}|j dkrt|j	}|j dkrt
||j|j}nt
||t}q|j d	krt|t|j	d
}q|j dkr"t|t|d
}q|j dkr@t|t|d
}q|j dkr^t|t|d
}q|j dkrxt||d
}q|j dkrt||d
}q|j dkrt||j|j}qtdt||j f qW |rt||d}|S )zB
    http://www.w3.org/TR/sparql11-query/#convertGraphPattern
    	SubSelectr   ZTriplesBlockr=   r#   r$   ZOptionalGraphPatternr&   ZMinusGraphPattern)r   r   ZGroupOrUnionGraphPatternZGraphGraphPatternZ
InlineDataZServiceGraphPatternr'   Bindz*Unknown part in GroupGraphPattern: %s - %s)r   r   rq   )r#   r'   )rQ   r   	translaterV   rg   rc   r#   r$   r\   r"   r%   r   r   r   r   r   rk   rl   rn   r'   r(   rL   typer&   )rh   rf   rj   r   Gri   r   r   r   r\   	  sL    





r\   c               @   s   e Zd Zdd ZdS )StopTraversalc             C   s
   || _ d S )N)rv)selfrv   r   r   r   __init__B  s    zStopTraversal.__init__N)__name__
__module____qualname__rx   r   r   r   r   ru   A  s   ru   c             C   s   d S )Nr   )r]   r   r   r   rJ   F  s    rJ   c                s   | }|dk	r|S | dkr dS t | ttfrB fdd| D S t | trdt fdd| D S t | trx$| j D ]\}}t| | |< qxW  | }|dk	r|S | S )zm
    Traverse a parse-tree, visit each node

    if visit functions return a value, replace current node
    Nc                s   g | ]}t | qS r   )	_traverse)r0   r1   )r_   visitPrer   r   r3   T  s    z_traverse.<locals>.<listcomp>c                s   g | ]}t | qS r   )r|   )r0   r1   )r_   r}   r   r   r3   V  s    )r/   rX   r   tupler
   itemsr|   )ra   r}   r_   _ekvalr   )r_   r}   r   r|   F  s     

r|   c             C   s   d S )Nr   )r]   vr   r   r   rJ   c  s    c                sj   g }t | tttfr( fdd| D }n8t | tr`x,| j D ] \}}|dk	r<|jt|  q<W  | |S )zm
    Traverse a parse-tree, visit each node

    if visit functions return a value, replace current node
    c                s   g | ]}t | qS r   )_traverseAgg)r0   r1   )visitorr   r   r3   m  s    z _traverseAgg.<locals>.<listcomp>N)r/   rX   r   r~   r
   r   rc   r   )ra   r   r*   r   r   r   )r   r   r   c  s    
r   c             C   s   d S )Nr   )r]   r   r   r   rJ   x  s    c             C   s   d S )Nr   )r]   r   r   r   rJ   y  s    c             C   sD   yt | ||}|dk	r|S |S  tk
r> } z|jS d}~X nX dS )z
    Traverse tree, visit each node with visit function
    visit function may raise StopTraversal to stop traversal
    if complete!=None, it is returned on complete traversal,
    otherwise the transformed tree is returned
    N)r|   ru   rv   )treer}   r_   completerstr   r   r   r`   w  s    	r`   c             C   s"   t | tr| jjdrtddS )zL
    Traverse parse(sub)Tree
    return true if any aggregates are used
    
Aggregate_TN)r/   r
   rQ   
startswithru   )r1   r   r   r   _hasAggregate  s    
r   c             C   s@   t | tr<| jjdr<|j|  tdt| }|| d< |S dS )zR
    Collect Aggregates in A
    replaces aggregates with variable references
    r   z
__agg_%d__r*   N)r/   r
   rQ   r   rc   r   r8   )ra   ri   Zaggvarr   r   r   _aggs  s
    
r   c             C   sf   t | tr|j|  t | trb| jdkr8|j| j | S | jdkrb| jr^|jdd | jD  | S dS )z&
    Find all variables in a tree
    rp   ro   c             s   s   | ]}|j p|jV  qd S )N)r(   evar)r0   r   r   r   r   r6     s    z_findVars.<locals>.<genexpr>N)r/   r   r;   r
   rQ   r(   
projectionupdate)r1   r*   r   r   r   	_findVars  s    




r   c             C   s   t | trt| gS t | tr| jdkr4t | d< nx| jdkrdttjdd t|| D t | d< nHtttj|t | d< | jdkr| j	rtdd | j	D }nt }|S | d S ttj|t S )	zE
    find which variables may be bound by this part of the query
    ZRelationalExpressionZ_varsr'   c             S   s   g | ]\}}|d kr|qS )r   r   )r0   childrV   r   r   r   r3     s    z_addVars.<locals>.<listcomp>ro   c             s   s   | ]}|j p|jV  qd S )N)r(   r   )r0   r   r   r   r   r6     s    z_addVars.<locals>.<genexpr>)
r/   r   r>   r
   rQ   r   operatoror_zipr   )r1   childrensr   r   r   _addVars  s     





r   c             C   s<   t | tr| jjdr| S t | tr8|| kr8td| dS dS )zO
    For each unaggregated variable V in expr
    Replace V with Sample(V)
    r   Aggregate_Sample)varsN)r/   r
   rQ   r   r   )ra   r   r   r   r   _sample  s    r   c             C   s   t | trt| S d S )N)r/   r   simplifyFilters)ra   r   r   r   _simplifyFilters  s    
r   c             C   s(  g }g }| j rVxF| j D ]<}|jrt|jtjt|jd|_t|jtjt|d|_qW t| jt	ddrt| jt| _t| jtjt|d t| j
t	ddrt| j
t| _
t| j
tjt|d | j rxN| j D ]D}|jrtdt|d  }|jtd|j|d |j||jf qW td	||d
|fS )N)r   )ri   F)r   z
__agg_%d__r=   r   )r   r*   ZAggregateJoin)ri   r   )r   r   r`   r   	functoolspartialr   r   havingr   orderbyr(   r   r8   rc   r
   )qMEri   r   rv   r   r   r   translateAggregates  s(    r   c             C   s|   g }| j s|S | js|S t| jd tsNxJ| jD ]}|j| j d |i q0W n&x$| jD ]}|jtt| j | qVW t|S )Nr   )r(   valuer/   rX   rc   dictr   r+   )r   r*   r   valsr   r   r   rm     s    rm   c             C   s  t | t t| jtd| _t }t| jtjt|d t	| j}d}| j
rg }xD| j
jD ]8}t|tr|jdkrt||j|j}|j}|j| qXW t||d}d}nFt| jtddst| jtddstdd	 | jpg D rt|d
}d}|rt| |\}}ng }| jr"tt| jj |d}| jr@t|tt| jd}| jsRt |}nrt  }xj| jD ]`}|jr||kr|j|j n:|j!r||kr|j|j! |j|j|j!f nt"dq`W x|D ]\}	}t||	|}qW | jrt#|dd | jjD }t$||}| j%rH| j%dkr0td|d
}n| j%dkrHtd|d
}| j&rd}
| j&j'dk	rn| j&j'j( }
| j&j)dk	rtd||
| j&j)j( d}ntd||
d}||fS )z=
    http://www.w3.org/TR/sparql11-query/#convertSolMod

    )r_   )r*   FZGroupAs)r   r   T)r   c             s   s$   | ]}|j rt|jtd dV  qdS )F)r   N)r   r`   r   r   )r0   r1   r   r   r   r6   6  s   ztranslate.<locals>.<genexpr>)r   )r   r   )r   r   zI expected a var or evar here!c             S   s   g | ]}t d |j|jdqS )ZOrderCondition)r   order)r
   r   r   )r0   rE   r   r   r   r3   _  s   ztranslate.<locals>.<listcomp>ZDISTINCTDistinctZREDUCEDZReducedr   NSlice)r   startlength)r   r   )*r|   r   r`   whererY   r>   r   r   r   r\   groupby	conditionr/   r
   rQ   r'   r   r(   rc   r.   r   r   r   anyr   r   r&   r   ZvaluesClauser   r   rm   rX   r   rL   r   r,   modifierZlimitoffsetoffsetZtoPythonlimit)r   ZVSr   Z	aggregateZ
conditionsrE   r   r-   r   ra   r   r   r   r   rr     sx    







rr   c             C   sz   t | trv| jdkrZ| jjdkr6t| jjdkr6| jS | jjdkrvt| jjdkrv| jS n| jdkrvt| j| d< | S dS )zRemove joins to empty BGPsr   r#   r   r$   N)r/   r
   rQ   r   r8   r$   r   rH   )r]   r   r   r   r   y  s    


r   c             C   sD   t | tr<| jdkr$t|| d< dS | jdkr2dS t|S ndS dS )	z
    Some things can be lazily joined.
    This propegates whether they can up the tree
    and sets lazy flags for all joins
    r   ZlazyFr   r   TN)r   r   )r/   r
   rQ   all)r]   r   r   r   r   analyse  s    



r   c             C   s   |d krt  }d|_|r||_|rDx |j D ]\}}|j|| q,W x@| D ]8}|jdkrb|j|_qJ|jdkrJ|j|j|j|j qJW |S )N ZBaseZ
PrefixDecl)r   baser   bindrQ   ZiriprefixrR   )r   r   initNsrT   r   r   r1   r   r   r   translatePrologue  s    



r   c             C   s\   | j rt | j }ng }tjt}| jrTx,| jD ]"}|j r.||j  t |j 7  < q.W ||fS )N)r$   r?   r@   rX   ZquadsNotTriplesr!   )quadsZ
alltriplesZallquadsr   r   r   r   translateQuads  s    
r   c             C   s   | j dkrn| j dkrn| j dkrLt| j\}}|| d< || d< | j dkrnj| j dkr| jrxt| jj\| jd< | jd< | jrt| jj\| jd< | jd< t| j| d< ntd|  || _| S )NLoadClearDropCreateAddMoveCopy
InsertData
DeleteDataDeleteWherer   r$   ZModifyr   z$Unknown type of update operation: %s)r   r   r   r   )r   r   r   )r   r   r   )r   r   )	rQ   r   r   deleteinsertr\   r   rL   rT   )urT   rD   r   r   r   r   translateUpdate1  s&    




r   c             C   s|   g }d}| j s|S xdt| j| j D ]R\}}t||||}t|tjt|dd}t|t	}t|t
d}|jt|| q"W |S )z=
    Returns a list of SPARQL Update Algebra expressions
    N)rT   )r_   )requestr   rT   r   r`   r   r   rU   r|   r   rY   rc   r   )r   r   r   r*   rT   r   r   r   r   r   translateUpdate  s    
r   c       	      C   s   t | d ||}t| d tjt|dd| d< t| d \}}| d j}| d jdkr| d jrnt	| d jnd}t
| d j|||d}nt
| d j|||d}t|td}t|td	 t|t t||S )
z|
    Translate a query-parsetree to a SPARQL Algebra Expression

    Return a rdflib.plugins.sparql.sparql.Query object
    r   r=   )rT   )r_   ZConstructQueryN)r   templatedatasetClause)r   r   r-   )r   )r   r`   r   r   rU   rr   r   rQ   r   r$   r
   r   r   r   r   r	   )	r   r   r   rT   Pr-   r   r   r*   r   r   r   translateQuery  s    	


r   c                sL   d fdd	 y | j  W n* tk
rF   x| D ]} | q2W Y nX d S )N    c                sj   t | tst|  d S td| jf  x2| D ]*}td||f dd  | | |d  q,W td|  d S )Nz%s(z%s%s = )endz    z%s))r/   r
   printrQ   )r   indr   )ppr   r   r     s    

zpprintAlgebra.<locals>.pp)r   )ZalgebraAttributeError)r   r1   r   )r   r   pprintAlgebra  s    
r   __main__)parserr=   )N)N)N)NN)NN)NN)[__doc__
__future__r   r   r   r?   r   Zrdflibr   r   r   r   Zrdflib.plugins.sparql.sparqlr   r	   Z!rdflib.plugins.sparql.parserutilsr
   r   Zrdflib.plugins.sparql.operatorsr   r   r   r   Zrdflib.pathsr   r   r   r   r   	pyparsingr   r   r   r   r   r   r    r#   r%   r&   r'   r+   r,   r.   r:   rH   r$   rU   rY   rb   rg   rk   rl   rn   r\   rL   ru   r|   r   r`   r   r   r   r   r   r   r   rm   rr   r   r   r   r   r   r   r   ry   sysZrdflib.plugins.sparqlr   os.pathospathexistsargvfiler   Z
parseQueryZpqr   Ztqr   r   r   r   <module>   s   

(	-8
"b


"


