o
    'i,                     @   sr  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ dZG dd dZ	G dd dZ
d	ed
edefddZdededefddZdedefddZdedededededededefddZdededefdd Zd!ededefd"d#Zd!edefd$d%Zd&edefd'd(Zd!ed)eddfd*d+Zd,ededdfd-d.Zd/ed0eddfd1d2Zd6d3d4Zed5kre  dS dS )7    N)reduce)PathaZ  
.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: 180px;
	text-align: center;
	background-color: #fff100;
}
.custom-tooltip {
  position: relative;
  display: inline-block;
}

.tooltip-text {
  visibility: hidden;
  background-color: #333;
  color: #fff;
  text-align: center;
  padding: 0px;
  border-radius: 1px;

  /* Positioning */
  position: absolute;
  z-index: 1;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 8px;

  /* Tooltip Arrow */
  width: 400px;
}

.custom-tooltip:hover .tooltip-text {
  visibility: visible;
}
c                   @   s>   e Zd ZdededdfddZdeddfdd	ZdddZdS )
NodeTimingphasetimereturnNc                 C   s   || _ || _d| _d S Nr   )r   r   
percentage)selfr   r    r   Y/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/duckdb/query_graph/__main__.py__init__O   s   
zNodeTiming.__init__
total_timec                 C   s   | j | | _d S N)r   r	   )r
   r   r   r   r   calculate_percentageU   s   zNodeTiming.calculate_percentagerc                 C   s   | j |j  }t| j|S r   )r   r   r   )r
   r   r   r   r   r   combine_timingX   s   zNodeTiming.combine_timing)r   r   r   r   )__name__
__module____qualname__strfloatr   r   r   r   r   r   r   r   N   s    r   c                   @   sp   e Zd ZdddZdeddfddZdedee fd	d
ZdedefddZ	dee fddZ
defddZdS )
AllTimingsr   Nc                 C   s
   i | _ d S r   phase_to_timingsr
   r   r   r   r   _      
zAllTimings.__init__node_timingc                 C   s4   |j | jv r| j|j  | d S |g| j|j < d S r   )r   r   append)r
   r   r   r   r   add_node_timingb   s   zAllTimings.add_node_timingr   c                 C   s
   | j | S r   r   r
   r   r   r   r   get_phase_timingsh   r   zAllTimings.get_phase_timingsc                 C   s   t tj| j| S r   )r   r   r   r   r    r   r   r   get_summary_phase_timingsk      z$AllTimings.get_summary_phase_timingsc                    s.   t  j }|j fddd |  |S )Nc                    s     | jS r   )r"   r   )xr   r   r   <lambda>p   s    z'AllTimings.get_phases.<locals>.<lambda>)key)listr   keyssortreverse)r
   phasesr   r   r   
get_phasesn   s   zAllTimings.get_phasesc                 C   s$   d}| j D ]
}|| |j7 }q|S r   )r   r"   r   )r
   total_timing_sumr   r   r   r   get_sum_of_all_timingst   s   
z!AllTimings.get_sum_of_all_timingsr   N)r   r   r   r   r   r   r   r'   r!   r"   r,   r   r.   r   r   r   r   r   ^   s    
r   fpathflagsr   c                 C   s   t | j|ddS )Nutf8)modeencoding)r   open)r0   r1   r   r   r   	open_utf8{   r#   r6   top_nodequery_timingsc                 C   s<   t | d t| d }|| | d D ]}t|| qd S )Noperator_typeoperator_timingchildren)r   r   r   get_child_timings)r7   r8   r   childr   r   r   r<      s
   
r<   fractionc                 C   s   t dtd| } d}d}t|d |d |d  |   }t|d |d |d  |   }t|d |d |d  |   }d|d|d|dS )Nr      )      rA   )r@            #02x)maxminint)r>   
light_pink	dark_pinkr   gbr   r   r   get_pink_shade_hex   s      rN   nameresultcpu_timecardestwidth
extra_infoc                 C   s   dt t||  d}d| d}|d7 }| dkrdn| dd	}	t|d
}
|d|	 d|
 d7 }|d| d7 }|dkrW|d| d7 }|d| d7 }|d| d7 }|d7 }|d7 }|S )Nzbackground-color: ;z*<span class="tf-nc custom-tooltip" style="z">z<div class="node-body">INVALIDBRIDGE_ z.4fz<p><b>z</b> </p><p>time: z seconds</p>z<span class="tooltip-text"> z </span>r   z<p>cardinality: z</p>z<p>estimate: z
<p>width: z
 bytes</p>z</div>z</span>)rN   r   replace)rO   rP   rQ   rR   rS   rT   rU   
node_stylebodynew_nameformatted_numr   r   r   get_node_body   s   r`   
json_graphc                 C   s   d}d}d}d}| d D ]}| d | }|dkrt |}q|| d| d7 }q| d	 }t | d
 td| }	tdd|}tdd|}t| d | d ||||	tdd|}
d}t| d dkrx|d7 }| d D ]	}|t||7 }qj|d7 }||
 | | S )Nz<li>z</li> r   rU   zEstimated Cardinalityz: z <br>operator_cardinalityresult_set_sizer?   z__internal_\s*__zcompress_integral\s*compressr9   r:   z,\s*z, r;   z<ul>z</ul>)rI   rG   resubr`   lengenerate_tree_recursive)ra   rQ   node_prefix_htmlnode_suffix_htmlrU   estimater&   valuecardinalityrT   	node_bodychildren_htmlr=   r   r   r   rj      s:   

rj   
graph_jsonc              
   C   s   t | }t|| t|dp|d}d}d}d}| }| }|td| |td| ddg|}|D ]4}	|	|	}
|

| |	dksP|	dkrVd|	 d	n|	}|d
| d|
j dt|
jd d d  d7 }q<||7 }|| S )Nr:   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.   r,   r   r   r"   r   r   r   r	   )rr   r8   ra   r   
table_head
table_body	table_endexecution_time
all_phasesr   summarized_phasephase_columnr   r   r   generate_timing_html   s0   




 r   c                 C   s<   t | }t|d }d}d}t|d d |}|| | S )NrQ   z&<div class="tf-tree tf-gap-sm"> 
 <ul>z</ul> </div>r;   r   )rv   rw   r   rj   )rr   ra   rQ   tree_prefixtree_suffix	tree_bodyr   r   r   generate_tree_html   s   
r   
json_inputc                 C   sB   ddl m} t| d}|dd|d d|d 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_htmlr[   )r   r   html_outputr   r   r   generate_ipython  s   
r   include_meta_infoc                 C   s*   d}d}|t d 7 }|d7 }||dddS )NzP<link rel="stylesheet" href="https://unpkg.com/treeflex/dist/css/treeflex.css">
z<style>

z	</style>
rb   )treeflex_css
duckdb_cssr   r   )
qgraph_css)rr   r   r   r   r   r   r   generate_style_html  s
   r   rv   c                 C   s   t | d d | d S )Nr;   r   )r<   )rv   r8   r   r   r   rx     s   rx   
input_fileoutput_filec           	      C   s   t  }t| d}| }W d    n1 sw   Y  t|d}t||}t|}t|d,}d}|d|d }|d|d }|d	|}|d
|}|| W d    d S 1 s^w   Y  d S )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   r6   readr   r   r   r[   write)	r   r   r8   ftextr   timing_tabletree_outputhtmlr   r   r   translate_json_to_html  s   


"r   c                  C   s   t jddd} | jddd | jdddd	 | jd
dddd |  }|j}|j}|js@d|v r7|dd}ntd td nd|jv rI|j}ntd td |j	}t
|| |rktj	dt|  dd d S d S )NzQuery Graph GeneratorzjGiven 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 jsonr?   z/please provide valid .html file for output namezfile://rD   )new)argparseArgumentParseradd_argument
parse_argsr   outr[   printexitr5   r   
webbrowserr   resolve)parserargsinputoutputopen_outputr   r   r   mainC  s0   


 r   __main__r/   )r   rv   rg   r   	functoolsr   pathlibr   r   r   r   r   objectr6   r<   r   rN   rI   r`   rj   r   r   r   boolr   rx   r   r   r   r   r   r   r   <module>   s0    F*'&
&"
