
    XIg&                     h   d dl Z d dlZd dlZd dlZd dlmZ d dlZdZ G d d      Z G d d      Z	de
d	e
d
efdZdeded
e
fdZdddddddddddddZde
de
dede
d
e
f
dZded
e
fdZdeded
efdZded
e
fd Zd!e
d
e
fd"Zde
d#ed
dfd$Zd%e
ded
dfd&Zd'e
d(e
d
dfd)Zd,d*Zed+k(  r e        yy)-    N)reducea  
.styled-table {
	border-collapse: collapse;
	margin: 25px 0;
	font-size: 0.9em;
	font-family: sans-serif;
	min-width: 400px;
	box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.styled-table thead tr {
	background-color: #009879;
	color: #ffffff;
	text-align: left;
}
.styled-table th,
.styled-table td {
	padding: 12px 15px;
}
.styled-table tbody tr {
	border-bottom: 1px solid #dddddd;
}

.styled-table tbody tr:nth-of-type(even) {
	background-color: #f3f3f3;
}

.styled-table tbody tr:last-of-type {
	border-bottom: 2px solid #009879;
}

.node-body {
	font-size:15px;
}
.tf-nc {
	position: relative;
	width: 250px;
	text-align: center;
	background-color: #fff100;
}
c                   D    e Zd ZdededefdZdeddfdZded	edefd
Zy)
NodeTimingphasetimereturnc                 .    || _         || _        d| _        y Nr   )r   r   
percentage)selfr   r   s      X/var/www/html/answerous/venv/lib/python3.12/site-packages/duckdb/query_graph/__main__.py__init__zNodeTiming.__init__4   s    
	    
total_timeNc                 ,    | j                   |z  | _        y N)r   r   )r   r   s     r   calculate_percentagezNodeTiming.calculate_percentage:   s    ))j0r   lrc                 `    | j                   |j                   z   }t        | j                  |      S r   )r   r   r   )r   r   r   s      r   combine_timingzNodeTiming.combine_timing=   s$    VVaff_
!'':..r   )	__name__
__module____qualname__strfloatobjectr   r   r    r   r   r   r   2   sI    c  6 1u 1 1/& /V / /r   r   c                   B    e Zd Zd ZdefdZdefdZdefdZd Z	d Z
y	)

AllTimingsc                     i | _         y r   phase_to_timings)r   s    r   r   zAllTimings.__init__E   s
     "r   node_timingc                     |j                   | j                  v r)| j                  |j                      j                  |       y |g| j                  |j                   <   y r   )r   r#   append)r   r$   s     r   add_node_timingzAllTimings.add_node_timingH   sP     5 55!!+"3"34;;KH4?=k//0r   r   c                      | j                   |   S r   r"   r   r   s     r   get_phase_timingszAllTimings.get_phase_timingsN   s    $$U++r   c                 P    t        t        j                  | j                  |         S r   )r   r   r   r#   r)   s     r   get_summary_phase_timingsz$AllTimings.get_summary_phase_timingsQ   s     j//1F1Fu1MNNr   c                      t         j                  j                               }|j                   fd       |j	                          |S )Nc                 :    j                  |       j                  S r   )r,   r   )xr   s    r   <lambda>z'AllTimings.get_phases.<locals>.<lambda>V   s    4#A#A!#D"J"J r   )key)listr#   keyssortreverse)r   phasess   ` r   
get_phaseszAllTimings.get_phasesT   s:    d++0023JKr   c                     d}| j                   j                         D ]   }|| j                  |      j                  z  }" |S r
   )r#   r3   r,   r   )r   total_timing_sumr   s      r   get_sum_of_all_timingsz!AllTimings.get_sum_of_all_timingsZ   sJ    **//1 	KE > >u E J JJ	Kr   N)r   r   r   r   r   r'   r   r*   r,   r7   r:   r   r   r   r    r    C   s9    #A: A,s ,Os O r   r    fpathflagsr   c                     t        | |d      S )Nutf8)encoding)open)r;   r<   s     r   	open_utf8rA   a   s    uv..r   top_nodequery_timingsc                     t        | d   t        | d               }|j                  |       | d   D ]  }t        ||        y )Noperator_typeoperator_timingchildren)r   r   r'   get_child_timings)rB   rC   r$   childs       r   rH   rH   e   sJ    Xo6hGX>Y8Z[K!!+.*% 0%/0r   z#ffffbaz#ffb3baz#baffc9z#ffdfbaz#bae1ffz#facd60z#1ac0c6)	HASH_JOIN
PROJECTIONSEQ_SCANUNGROUPED_AGGREGATEFILTERORDER_BYPERFECT_HASH_GROUP_BYHASH_GROUP_BYNESTED_LOOP_JOINSTREAMING_LIMITCOLUMN_DATA_SCANTOP_Nnameresultcardinality
extra_infoc                     d}| j                         }|t        v rdt        |    d}d| d}|dz  }| j                  dd      }|d	| d
| dz  }|dz  }|d| dz  }|dz  }|d| dz  }|dz  }|dz  }|S )N zbackground-color: ;z<span class="tf-nc" style="z">z<div class="node-body">_ z<p> <b>z (zs) </b></p>z<p> ---------------- </p>z<p> z </p>z<p> cardinality = z</div>z</span>)strip	color_mapreplace)rV   rW   rX   rY   
node_stylestripped_namebodynew_names           r   get_node_bodyrf   |   s    JJJLM	!))M*B)C1E
+J<s;D''D||C%HghZr&55D'(Dd:,e$$D'(D U33DHDIDKr   
json_graphc                     d}d}d}| d   D ]  }|| d| d   |    dz  } t        | d   | d   | d	   |      }d}t        | d
         dk\  r"|dz  }| d
   D ]  }|t        |      z  } |dz  }||z   |z   |z   S )Nz<li>z</li>r[   rY   z: z <br>rE   rF   operator_cardinalityrG      z<ul>z</ul>)rf   lengenerate_tree_recursive)rg   node_prefix_htmlnode_suffix_htmlrY   r1   	node_bodychildren_htmlrI   s           r   rl   rl      s    J,' ER
< 8 =>eDD
E j9():;()?@(*I
 M
:j!"a'
+ 	<E4U;;M	< i'-7:JJJr   
graph_jsonc                 N   t        j                  |       }t        ||       t        |j	                  d      xs |j	                  d            }d}d}d}|j                         }|j                         }|j                  t        d|             |j                  t        d|             ddg|z   }|D ]f  }	|j                  |	      }
|
j                  |       |	dk(  s|	dk(  rd|	 d	n|	}|d
| d|
j                   dt        |
j                  dz  d       dz  }h ||z  }||z   S )NrF   latencyz
	<table class="styled-table"> 
		<thead>
			<tr>
				<th>Phase</th>
				<th>Time</th>
				<th>Percentage</th>
			</tr>
		</thead>z<tbody>z</tbody></table>z
TOTAL TIMEzExecution Timez<b>z</b>z
	<tr>
			<td>z</td>
            <td>d      z%</td>
    </tr>
)jsonloadsgather_timing_informationr   getr:   r7   r'   r   r,   r   r   roundr   )rq   rC   rg   r   
table_head
table_body	table_endexecution_time
all_phasesr   summarized_phasephase_columns               r   generate_timing_htmlr      sX   J'Jj-8z~~&78UJNN9<UVJJ J"I"99;N))+J!!*\:"FG!!*-=~"NO 01J>J 
(BB5I--j9,1\,AUN^E^UG4(di ~ !&&' ('2236q9: ;	 	
	
 )J
""r   c                 f    t        j                  |       }d}d}t        |d   d         }||z   |z   S )Nz&<div class="tf-tree tf-gap-lg"> 
 <ul>z</ul> </div>rG   r   )rv   rw   rl   )rq   rg   tree_prefixtree_suffix	tree_bodys        r   generate_tree_htmlr      s@    J'J=K K (
:(>q(ABI"[00r   
json_inputc                     ddl m} t        | d      } |dj                  d|d         j                  d|d         j                  d	|d
               S )Nr   )HTMLFzW
	${CSS}
	${LIBRARIES}
	<div class="chart" id="query-profile"></div>
	${CHART_SCRIPT}
	z${CSS}cssz${CHART_SCRIPT}chart_scriptz${LIBRARIES}	libraries)IPython.core.displayr   generate_htmlra   )r   r   html_outputs      r   generate_ipythonr      sb    )
E2K 
 ghE(:;GGDUGRSaGb=ddkdkK0e23 3r   include_meta_infoc                 :    d}d}|t         dz   z  }|dz  }||dddS )NzP<link rel="stylesheet" href="https://unpkg.com/treeflex/dist/css/treeflex.css">
z<style>

z	</style>
r[   )treeflex_css
duckdb_cssr   r   )
qgraph_css)rq   r   r   r   s       r   generate_style_htmlr      s;    jL
C:C<C$	 r   rv   c                 (    t        | d   d   |       y )NrG   r   )rH   )rv   rC   s     r   rx   rx      s     d:&q)=9r   
input_fileoutput_filec                    t               }t        | d      5 }|j                         }d d d        t        d      }t	        ||      }t        |      }t        |d      5 }d}|j                  d|d         }|j                  d|d         }|j                  d	|      }|j                  d
|      }|j                  |       d d d        y # 1 sw Y   xY w# 1 sw Y   y xY w)Nr   Tzw+aT  <!DOCTYPE html>
<html>
	<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width">
	<title>Query Profile Graph for Query</title>
	${TREEFLEX_CSS}
	<style>
		${DUCKDB_CSS}
	</style>
</head>
<body>
	<div id="meta-info"></div>
	<div class="chart" id="query-profile">
		${TIMING_TABLE}
	</div>
	${TREE}
</body>
</html>
z${TREEFLEX_CSS}r   z${DUCKDB_CSS}r   z${TIMING_TABLE}z${TREE})r    rA   readr   r   r   ra   write)	r   r   rC   ftextr   timing_tabletree_outputhtmls	            r   translate_json_to_htmlr      s    LM	:s	# qvvx &dD1K'm<L$T*K 
;	% ( ||-{>/JK||O[-FG||-|<||I{3	3   s   C
A"C
CCc                     t         j                  d   dk  rt        d       t        d       t	        j
                  dd      } | j                  dd	
       | j                  ddd       | j                  dddd       | j                         }|j                  }|j                  }|j                  s.d|v r|j                  dd      }nHt        d       t        d       n1d|j                  v r|j                  }nt        d       t        d       |j                  }t        ||       |r8t        j                  dt        j                  j!                  |      z   d       y y )Nr      zPlease use python3rj   zQuery Graph GeneratorzbGiven a json profile output, generate a html file showing the query graph and timings of operators)progdescriptionprofile_inputzprofile input in json)helpz--outF)requireddefaultz--open
store_trueT)r   actionr   z.jsonz.htmlz%please provide profile output in jsonz/please provide valid .html file for output namezfile://   )new)sysversion_infoprintexitargparseArgumentParseradd_argument
parse_argsr   outra   r@   r   
webbrowserospathabspath)parserargsinputoutputopen_outputs        r   mainr      s/   
Q"#Q$$$xzF .EF
%?
5tTDEXXF88e]]7G4F9:GdhhXXFCDG))K5&)	BGGOOF$;;C r   __main__)r   N)rv   r   r   r   	functoolsr   r   r   r   r    r   r   rA   rH   r`   r   rf   rl   r   r   r   boolr   rx   r   r   r   r   r   r   <module>r      s~    	 
   '
T/ /"   </S / / /0 0v 0# 0 $&! !	  S u # RU (K K3 K.##V ##F ##v ##L16 1c 13 3 3
C 
D 
T 
:C : :4 :#s # # #L DF zF r   