<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3443854162607009076</id><updated>2011-12-12T21:21:04.360-02:00</updated><category term='others'/><category term='linux'/><category term='developer'/><category term='java'/><category term='c++'/><category term='firebird'/><category term='nf-e'/><title type='text'>asfernandes</title><subtitle type='html'>Firebird, Wicket, Java, C++, Linux and something else</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-458796742082581529</id><published>2011-10-22T01:15:00.001-02:00</published><updated>2011-10-22T01:15:44.700-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Como se tornar (ou não) um "Firebird Developer"</title><content type='html'>Recentemente eu divulguei em meu twitter que estava fazendo sete anos do meu primeiro commit no projeto Firebird. Daí citaram isso no FirebirdNews e em newsletter da Firebase.&lt;br /&gt;&lt;br /&gt;Estou dizendo isso porque apareceram algumas pessoas com aquele tipo comum de questionamento "Como entrar para o time Firebird?". O problema é que, como citado na newsletter da Firebase, desses sete anos pra cá nenhum desenvolvedor se juntou ao Firebird (core). Isso mesmo, com exceção de um ou outro patch específico (geralmente dos mantenedores das distros Linux), o Firebird é desenvolvido pelas mesmas poucas pessoas há mais de sete anos.&lt;br /&gt;&lt;br /&gt;Sempre respondi esses e-mails, mas geralmente a "vontade" da pessoa já termina aí. E olha que sempre respondi com mais educação do que estou usando pra escrever esse post.&lt;br /&gt;&lt;br /&gt;Então vou colocar o que realmente penso sobre isso.&amp;nbsp;Em primeiro lugar, você não deve fazer essa pergunta&amp;nbsp;"Como entrar para o time Firebird?". A primeira coisa é aprender a usar o Google e se surgir alguma dúvida que não tenha uma resposta, aí sim pergunte sobre ela.&lt;br /&gt;&lt;br /&gt;É normal que você tenha dificuldade pra "se inserir" no projeto. Eu comecei a acompanhar o desenvolvimento do Firebird em dezembro de 2003 e meu primeiro commit foi em setembro de 2004, apesar de estar trabalhando ativamente desde junho ou julho. O Claudio Valderrama costumava dizer que eu era o único que tinha aprendido o código em algumas semanas, mas como podem ver foi alguns meses :), sem falar que até hoje eu não gosto nem de ver certos subsistemas (hello PAG, CCH, SDW...).&lt;br /&gt;&lt;br /&gt;Outra coisa são suas habilidades.&amp;nbsp;Não é normal que você não tenha no mínimo bons conhecimentos sobre C++, que é a linguagem usada no desenvolvimento do Firebird. Eu posso te afirmar com 98% de certeza que você não vai encontrar em um projeto open-source pessoas com vontade de te ajudar com coisas básicas.&lt;br /&gt;&lt;br /&gt;Digamos que você já esteja pensando que não quer isso (como todos os anteriores), mas tenha alguma dúvida ainda, então continuo minhas sugestões para que você não consiga :).&amp;nbsp;Não leia todos os posts das listas de discussões. Também não leia e tente entender todas as alterações feitas no código, que são enviadas pra lista firebird-checkins. Acho que foi aqui que falhei, pois desde aquele dezembro de 2003 não deixei de ler nenhuma das milhares de mensagens. E tenho certeza que todos os outros desenvolvedores ativos fizeram e fazem o mesmo.&lt;br /&gt;&lt;br /&gt;Se você também se ofendeu com esse post (caso tenha sido um dos que fez aquela pergunta), é melhor não perder seu tempo e desistir logo. Quem acompanha as listas firebird-devel e firebird-architect (e a firebird-admins, mas essa é fechada), sabe do que estou falando. As vezes (pra não dizer, muitas vezes) as discussões partem pro lado pessoal, e isso é a pior parte de fazer parte do projeto. Isso não é uma exclusividade do Firebird. Comparando com o Linux, por exemplo, é só procurar alguma mensagem do Linus Torvals na lkml e ver como a coisa geralmente funciona.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-458796742082581529?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/458796742082581529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=458796742082581529&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/458796742082581529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/458796742082581529'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2011/10/como-se-tornar-ou-nao-um-firebird.html' title='Como se tornar (ou não) um &quot;Firebird Developer&quot;'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-963516367113453142</id><published>2011-08-20T12:58:00.004-03:00</published><updated>2011-09-01T00:08:07.225-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Beautiful fonts in Ubuntu</title><content type='html'>In the old days, fonts in Linux were really ugly by default. There are patents involved, so it was possible to make them beautiful recompiling freetype with some options.&lt;br /&gt;&lt;br /&gt;Since some time, this is not necessary.&lt;br /&gt;&lt;br /&gt;But if you're like me, you may note that some fonts are very blurry in some applications, and you can't change that in the appearance config.&lt;br /&gt;&lt;br /&gt;To fix this, I put this &lt;a href="http://pastebin.com/U0humUR9"&gt;.fonts.conf&lt;/a&gt; in my home directory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-963516367113453142?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/963516367113453142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=963516367113453142&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/963516367113453142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/963516367113453142'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2011/08/beautiful-fonts-in-ubuntu.html' title='Beautiful fonts in Ubuntu'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-2989719128389093894</id><published>2011-05-01T14:05:00.005-03:00</published><updated>2011-05-01T14:19:25.455-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Ubuntu Natty Narwhal in VMware</title><content type='html'>&lt;div&gt;Here are some tips to use Ubuntu 11.04 Natty Narwhal on VMware.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First upgrade the host vmware (player) to the latest (3.1.4) version. Although the release notes mention nothing on Natty, the vmware-tools from this version compiles ok on the Natty kernel.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You may have some luck with the open-vm-tools. I didn't had much. It didn't recognized the machine as a VM, but still worked. I was having problems with the video looking very ugly and was thinking it was a vmware-tools problem, but looks like not. Below is a workaround to run on the terminal which makes things beautiful again:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;killall gnome-settings-daemon&lt;/div&gt;&lt;div&gt;gnome-settings-daemon &amp;amp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-2989719128389093894?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/2989719128389093894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=2989719128389093894&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/2989719128389093894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/2989719128389093894'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2011/05/ubuntu-natty-narwhal-in-vmware.html' title='Ubuntu Natty Narwhal in VMware'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-5622903814756928788</id><published>2011-04-20T14:54:00.006-03:00</published><updated>2011-04-20T15:01:07.742-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='developer'/><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>Alguns links de artigos e vídeos que acho interessantes</title><content type='html'>&lt;div style="background-color: transparent; "&gt;&lt;span class="Apple-style-span" &gt;&lt;span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;div style="background-color: transparent; font-family: 'Times New Roman'; white-space: normal; font-size: medium; "&gt;&lt;span id="internal-source-marker_0.7166498028673232" style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Segue alguns links de artigos e vídeos que acho interessantes:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.ted.com/talks/lang/por_br/jason_fried_why_work_doesn_t_happen_at_work.html"&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Porque não se trabalha no trabalho&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; - Jason Fried tem uma teoria radical sobre o trabalho, que diz que o escritório não é um bom lugar para fazê-lo.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.superempreendedores.com/empreendedorismo/guy-kawasaki-a-arte-do-comeco"&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;A Arte do Começo&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; - Vídeo com Guy Kawasaki dando uma palestra sobre como se começar um negócio.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://aurelianomartins.wordpress.com/2011/04/04/verdades-nao-tao-conhecidas-sobre-programacao/"&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Verdades não tão conhecidas sobre programação&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; - Tradução de um artigo que fala sobre a diferença entre programadores bons e ruins.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://akitaonrails.com/2009/03/30/off-topic-net-negative-producing-programmer"&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Net Negative Producing Programmer&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; - Fábio Akita fala sobre as diferenças entre os Codificadores (cowboys) e os Desenvolvedores.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=XvU12J0aYo4&amp;amp;feature=player_embedded"&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Ócio Criativo x Cowboy Coders&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; - Vídeo onde Daniel Cukier coloca a sua visão sobre a diferença entre Codificadores e Programadores, em alusão ao post (acima) do Fábio Akita.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://java.mn/2011/03/02/the-future-java-developer/"&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;The Future Java Developer&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; - O JavaMan Bruno Souza fala sobre o que desenvolvedores podem fazer para serem melhores profissionais no futuro (presente). Não é específico de Java.&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-5622903814756928788?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/5622903814756928788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=5622903814756928788&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/5622903814756928788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/5622903814756928788'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2011/04/alguns-links-de-artigos-e-videos-que.html' title='Alguns links de artigos e vídeos que acho interessantes'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-6667291263097013590</id><published>2011-01-01T20:05:00.006-02:00</published><updated>2011-01-01T20:31:52.271-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Novidades do Firebird 2.5 - Revista ClubeDelphi</title><content type='html'>Saiu na &lt;a href="http://www.devmedia.com.br/post-18855-Revista-Clube-Delphi-Edicao-125.html"&gt;edição 125&lt;/a&gt; da revista ClubeDelphi &lt;a href="http://www.devmedia.com.br/post-18849-Firebird-2-5.html"&gt;o artigo&lt;/a&gt; que escrevi sobre as novidades do Firebird 2.5. Esta edição também tem outra matéria sobre Firebird, entitulada "Aplicações com Firebird Embedded – Parte 1".&lt;div&gt;Já tinha recusado convites similares, mas desta vez resolvi topar o desafio. Não gosto muito de escrever, sou bastante perfeccionista e português não é uma das linguagens que eu domino (rs). Essa é uma das razões porque eu prefiro escrever em inglês no blog. Não que meu inglês seja bom, mas eu me sinto mais a vontade pra escrever mal. :)&lt;/div&gt;&lt;div&gt;Não vi a revista ainda. Espero que gostem, deu bastante trabalho.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-6667291263097013590?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/6667291263097013590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=6667291263097013590&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6667291263097013590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6667291263097013590'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2011/01/novidades-do-firebird-25-revista.html' title='Novidades do Firebird 2.5 - Revista ClubeDelphi'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-6267391664435360409</id><published>2010-12-18T10:36:00.002-02:00</published><updated>2010-12-18T11:11:35.794-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Introducing the boolean datatype</title><content type='html'>The support for a BOOLEAN datatype was the &lt;a href="http://tracker.firebirdsql.org/browse/CORE-726"&gt;third most voted&lt;/a&gt; feature in the Firebird tracker. The deal with it was about make it right and complete, having booleans expressions allowed where values are expected, and vice versa. Oracle did it wrong and they BOOLEAN is crap.&lt;div&gt;Yesterday I finished and committed this support for Firebird 3. You can use them like any other type. You can index it, aggregate by it and sort by it. If you have an index on a boolean field, you can also do indexed searches by its negated form (NOT field).&lt;/div&gt;&lt;div&gt;Three new literals are introduced: FALSE, TRUE and UNKNOWN (same as NULL).&lt;/div&gt;&lt;div&gt;Booleans are not implicitly convertible to any other datatype. But it's convertible to/from strings with CAST.&lt;/div&gt;&lt;div&gt;It's allowed to test booleans without compare with TRUE or FALSE. For example, "field1 OR field2" and "NOT field1" are valid expressions. It's also allowed to compare with others operators, including the new IS operator: "field1 IS FALSE".&lt;/div&gt;&lt;div&gt;Currently it has a terrible and bad hack. The new syntax would introduce a lot of parser conflicts related with trigger's INSERTING, UPDATING and DELETING expressions. These boolean expressions was non-reserved words and allowed to be used as column and variable names. The correct solution shall be to reserve these words and do not allow them to be used as names without double quotes.&lt;/div&gt;&lt;div&gt;As usual, this causes conflict opinions. I don't want to fight forever on this, so I make them work as triggers keywords in boolean expressions and as values in non-booleans expressions. This is much very compatible with previous versions, but is very confusing. For example, in "SELECT inserting, NOT inserting FROM test WHERE INSERTING and INSERTING IS TRUE" the INSERTING's are recognized as value, keyword, keyword and value.&lt;/div&gt;&lt;div&gt;I hope this clears people's minds and we have a better solution in the final version.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-6267391664435360409?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/6267391664435360409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=6267391664435360409&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6267391664435360409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6267391664435360409'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/12/introducing-boolean-datatype.html' title='Introducing the boolean datatype'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-5470221091873343313</id><published>2010-12-14T19:18:00.006-02:00</published><updated>2010-12-14T21:00:41.264-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='nf-e'/><title type='text'>Problema com Java 1.6.0_22 e NF-e de SP</title><content type='html'>Tivemos um problema, em ambiente interno de testes, com os webservices da Nota Fiscal Eletrônica do estado de São Paulo. O sistema estava sendo migrado de sistema operacional HP-UX (com Java distribuído pela HP) para um novo servidor com Red Hat Enterprise Linux (com Java da &lt;s&gt;Sun&lt;/s&gt; Oracle).&lt;div&gt;Ao acessar os webservices a aplicação congelava ou dava erros de "read timed out". O primeiro passo foi verificar se o servidor estava acessando a internet normalmente. Através do elinks era possível acessar sites via http e https normalmente. O webservice retornava corretamente o erro de falta de certificado cliente.&lt;/div&gt;&lt;div&gt;Depois tentei fazer conexões pela aplicação adicionando "?WSDL" às URLs. Nem o ambiente de homologação nem o de produção da NF-e funcionavam. Outros endereços http funcionavam normalmente pela aplicação. Pra debugar o problema, adicionamos a opção -Djavax.net.debug=all. A requisição era enviada mas não vinha a resposta.&lt;/div&gt;&lt;div&gt;Resolvi fazer o teste com os webservices de contingência do SCAN e funcionou. Analisando os logs da conexão, resolvi procurar sobre o termo no_renegotiation que estava aparecendo quando acontecia o erro.&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html"&gt;Esta página&lt;/a&gt; esclareceu o problema, que foi causado devido a uma alteração no Java para prevenir uma vulnerabilidade do protocolo TLS. Adicionamos as opções -Dsun.security.ssl.allowUnsafeRenegotiation=true e sun.security.ssl.allowLegacyHelloMessages=true até que o ambiente de SP seja atualizado.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-5470221091873343313?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/5470221091873343313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=5470221091873343313&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/5470221091873343313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/5470221091873343313'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/12/problema-com-java-16022-e-nf-e-de-sp.html' title='Problema com Java 1.6.0_22 e NF-e de SP'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-8666045115153500056</id><published>2010-10-04T21:16:00.009-03:00</published><updated>2010-10-04T21:36:38.904-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Firebird 2.5 Introduces New Audit Features and Improved Scalability</title><content type='html'>October 4, 2010&lt;br /&gt;&lt;br /&gt;The Firebird Project today announces Firebird 2.5, the fifth and newest major release of its open source relational database management system. Enhancements in this new release are pitched at better serving the needs of businesses of any scale, from embedded device to enterprise resource planning solutions.&lt;br /&gt;&lt;br /&gt;Philippe Makowski, President of the non-profit &lt;a href="http://www.firebirdsql.org/pop/index.php?op=ffoundation"&gt;Firebird Foundation&lt;/a&gt; observes that the Firebird 2.5 release is a very important step in Firebird's 10th anniversary year, not just for the Firebird Project but for the whole open-source world, too.&lt;br /&gt;&lt;br /&gt;"Today businesses all around the world are looking for mature, cost-effective solutions and Firebird 2.5 offers them a solution that is truly powerful and truly free", he noted.&lt;br /&gt;&lt;br /&gt;The mix of high performance, small footprint, supreme scalability, silent and simple installation and royalty-free deployment make Firebird a highly attractive choice for all types of software developers and vendors. Firebird deployments are well established around the globe, serving data to hundreds of thousands of business systems with hundreds of users and databases exceeding 300GB.&lt;br /&gt;&lt;br /&gt;Known Firebird installations number more than 2,000 each day, according to download statistics.&lt;br /&gt;&lt;br /&gt;"Many of our customers have Firebird databases with sizes from 200GB to 400GB and they keep growing", said Stewart Spink, CTO of &lt;a href="http://www.watermarktech.co.uk/"&gt;Watermark Software&lt;/a&gt;. "The performance improvements in Firebird 2.5 will ensure that their future demands will be satisfied completely."&lt;br /&gt;&lt;br /&gt;Alexander Shaposhnikov, CIO of medical distributor &lt;a href="http://www.profitmed.net/"&gt;Profitmed&lt;/a&gt; predicts that Firebird 2.5 will support the growth of Profitmed's business. "Currently we have a 65Gb database and 250 active users working 24x7. We intend to double both the size of the database and the number of users in two years and we have chosen Firebird 2.5 for this business-critical task."&lt;br /&gt;&lt;br /&gt;Firebird binaries are distributed for a variety of system and hardware platforms: Windows, Linux, MacOS, Solaris, HP-UX and more. Firebird runs on on x86, x64, PowerPC, Sparc and other hardware platforms, providing an easy migration mechanism between these diverse platforms.&lt;br /&gt;&lt;br /&gt;The V.2.5 release binaries ship for 32-bit and 64-bit Windows and Linux, with MacOSX x86 to follow. Other POSIX platform builds are likely to appear before the year is out, in response to demand.&lt;br /&gt;&lt;br /&gt;New features of Firebird 2.5&lt;br /&gt;&lt;ul&gt;&lt;li&gt;New SuperClassic Architecture  Firebird 2.5 introduces a new architecture, tagged "SuperClassic", to gain better leverage from multi-core and multi-CPU hardware environments and improve resource usage for systems with large numbers of users and huge databases.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Audit  System audit tracing and user trace sessions via the Services API enable nearly real-time monitoring and analysis of everything going on in a database&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Cross-database queries  Firebird 2.5 opens the way for Firebird database instances to query one another and to exchange information&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Enhanced user management  User management becomes accessible and flexible through SQL requests submitted from user databases&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Other features include autonomous transactions within PSQL modules (stored procedures, triggers, SQL blocks), support for regular expressions as arguments in SQL using the SIMILAR TO predicate, asynchronous cancellation of connections, enhancements of monitoring capabilities and much more.&lt;/li&gt;&lt;/ul&gt;Paul Beach, President and CEO of &lt;a href="http://www.ibphoenix.com/"&gt;IBPhoenix&lt;/a&gt;, an organisation that offers professional services and contributes to Firebird development, considers the new security features and the impressive scaling capability of Firebird 2.5 will be welcomed by many existing Firebird users.&lt;br /&gt;&lt;br /&gt;"In particular, it will help those in the finance and health industries to meet the growing requirements of their businesses", he notes, "especially in pushing the limits of performance."&lt;br /&gt;&lt;br /&gt;David Wilder, CTO of &lt;a href="http://www.basx.com.au/"&gt;Bas-X&lt;/a&gt;, welcomed the Firebird 2.5 release for its improved useability and flexibility. "It will enable our customers to turn over more transactions and run more concurrent users on the same hardware," he said.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pricing and Availability&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Firebird 2.5 is an open source database system that is available free of charge for any kind of usage, be it commercial, educational, non-profit or simply for private use. Both binary packages and the complete source code can be &lt;a href="http://www.firebirdsql.org/index.php?op=files&amp;amp;id=engine_250"&gt;downloaded&lt;/a&gt; at no cost through the Firebird Project website for immediate installation. No registration or activation is required.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;About the Firebird Foundation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.firebirdsql.org/index.php?op=ffoundation"&gt;Firebird Foundation&lt;/a&gt; is a non-profit organization with the goal to support the development and growth of the Firebird relational database system. The Foundation was incorporated in 2002 and is currently supported by more than &lt;a href="http://www.firebirdsql.org/index.php?op=ffoundation&amp;amp;id=members_alpha"&gt;300 active members&lt;/a&gt;, several of whom are also &lt;a href="http://www.firebirdsql.org/index.php?op=ffoundation&amp;amp;id=sponsorship"&gt;cash sponsors&lt;/a&gt;. It also accepts and manages donations of cash and resources from persons and organisations that are not regular members. The Foundation redistributes these funds as grants to some of the key workers in the Firebird Project. The Firebird Project has no other source of income.&lt;br /&gt;&lt;br /&gt;Media Contact: Alexey Kovyazin * +7 910 402 94 34 * admin AT mindthebird DOT com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-8666045115153500056?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/8666045115153500056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=8666045115153500056&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/8666045115153500056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/8666045115153500056'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/10/firebird-25-introduces-new-audit.html' title='Firebird 2.5 Introduces New Audit Features and Improved Scalability'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-5467009388014274295</id><published>2010-09-30T20:53:00.003-03:00</published><updated>2010-10-01T00:44:07.918-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Firebird 2.5 launch</title><content type='html'>&lt;a href="http://www.firebirdsql.org"&gt;Firebird&lt;/a&gt; 2.5 release date is set - it will be October 4th, 2010.&lt;br /&gt;&lt;br /&gt;Please join Philippe Makowski, President of Firebird Foundation, and Dmitry Yemanov, lead Firebird developer, at the &lt;a href="https://www.livemeeting.com/cc/fbcon2010/join?id=46D79S&amp;amp;role=attend"&gt;Launch Webinar&lt;/a&gt; devoted to the 5th major release of Firebird.&lt;br /&gt;&lt;br /&gt;It will take place at October 4th, 2010, at 13:00 GMT (10:00 pelo horário de Brasília).&lt;br /&gt;&lt;br /&gt;If you have any questions regarding Firebird 2.5, please feel free to contact &lt;a href="http://www.mindthebird.com"&gt;Mind the Bird&lt;/a&gt; campaign at &lt;a href="mailto:launch@mindthebird.com"&gt;launch@mindthebird.com&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-5467009388014274295?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/5467009388014274295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=5467009388014274295&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/5467009388014274295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/5467009388014274295'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/09/firebird-25-launch.html' title='Firebird 2.5 launch'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-7547937172084628787</id><published>2010-07-31T14:31:00.002-03:00</published><updated>2010-07-31T14:39:35.548-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Firebird 10th anniversary. How I came to it.</title><content type='html'>July 31th, 2010. Today &lt;a href="http://www.firebirdsql.org/"&gt;Firebird&lt;/a&gt; completes its 10th anniversary. The Firebird website has a set of &lt;a href="http://firebirdsql.org/index.php?op=history"&gt;history documents&lt;/a&gt; about how that started. It’s something you must read if you’re interested in Firebird.&lt;br /&gt;&lt;br /&gt;I’m sometimes asked about how I became one of its team members. So I’m going to tell something about this.&lt;br /&gt;&lt;br /&gt;First things first. My first contact with InterBase was with the one present in the Delphi 3 CD. Searches says it was InterBase 4.2. I must say I didn’t like it too much. But my main problem at the time was with SQL. Not with its syntax, but with the idea of manipulating a database with text commands, and not via an API in a programming language. Fortunately, I was a child and grew up since then. :-)&lt;br /&gt;&lt;br /&gt;The second important thing I remember about InterBase was about it becoming open source. This was something I liked, but just forgot soon later.&lt;br /&gt;&lt;br /&gt;Then sometime later I came to the &lt;a href="http://info.abril.com.br/downloads"&gt;Info&lt;/a&gt; download site and it had Firebird with a text saying something like “Download it, while it’s free”. I downloaded it (the 1.0 version) and saw on its website that there was no plan to make it non-free. I started using and liked it. What most attracted me was it excellent transaction control mechanism.&lt;br /&gt;&lt;br /&gt;I then started using the 1.5 RC versions and found a security bug on it. I tried to report on the SourceForge bug tracker without success. So I subscribed myself to firebird-devels mailing list and reported it there. That happened around in December 2003, and I never leaved the list since then. :-)&lt;br /&gt;&lt;br /&gt;Lurking at firebird-devel was a challenge. I didn’t understand much English nor the technical talks, but I stayed there reading every message. I started to read the source code and understand the subsystems. I then started following firebird-checkins mailing list, where I could better understand how each feature/fix got implemented.&lt;br /&gt;&lt;br /&gt;Around July 2004, I joined the Firebird PT_BR project to adapt for Firebird 1.5 the Brazilian collation done by Paulo Henrique Albanez for Firebird 1.0. I proposed different approach to definitively integrate it in Firebird and it was also rejected. So I got the work to do the “right” changes to the Firebird International Language (INTL) subsystem. In September 2004 I officially joined the project.&lt;br /&gt;&lt;br /&gt;What’s more nice about being there is that I can work with very competent team, delivering a good software to millions of people. And just doing something I really like, designing features, programming in C++ and working with compiler (SQL / PSQL) implementation...&lt;br /&gt;&lt;br /&gt;Long live Firebird!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-7547937172084628787?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/7547937172084628787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=7547937172084628787&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/7547937172084628787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/7547937172084628787'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/07/firebird-10th-anniversary-how-i-came-to.html' title='Firebird 10th anniversary. How I came to it.'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-3047828375655271072</id><published>2010-02-19T23:46:00.001-02:00</published><updated>2010-02-19T23:47:10.871-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Window functions (part3) - new functions</title><content type='html'>In the&amp;nbsp;&lt;a href="http://asfernandes.blogspot.com/2010/01/window-functions_19.html" id="odpv" title="first"&gt;first&lt;/a&gt;&amp;nbsp;and the&amp;nbsp;&lt;a href="http://asfernandes.blogspot.com/2010/01/window-functions-part2-cumulative_24.html" id="wif4" style="color:#551a8b" title="second"&gt;second&lt;/a&gt;&amp;nbsp;part of window function series, I talked about the &lt;font face="&amp;#39;Courier New&amp;#39;"&gt;OVER&lt;/font&gt; clause, with/without partitions and with/without ordering. Till then, no new function had been introduced, so it has about the already existing aggregate functions.&lt;br&gt;&lt;br&gt;&lt;div&gt;Now, new window-only functions has been introduced. I&amp;#39;ll separate them in two groups: ranking and navigational. Both set of functions can be used with/without partition/ordering, but them does not make much sense without ordering.&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;b&gt;Ranking functions (DENSE_RANK, RANK and ROW_NUMBER):&lt;/b&gt;&amp;nbsp;with these functions, one can create different type of incremental counters. Think about &lt;font face="&amp;#39;Courier New&amp;#39;"&gt;SUM(1) OVER (ORDER BY SALARY)&lt;/font&gt;, these functions does this type of thing, but all of them in different ways. Lets see an example query, also comparing with the SUM behavior.&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;select&lt;br&gt;&lt;/font&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id,&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary,&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;dense_rank() over (order by salary),&lt;br&gt;&lt;/font&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;rank() over (order by salary),&lt;br&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;row_number() over (order by salary),&lt;br&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sum(1) over (order by salary)&lt;br&gt;&lt;/font&gt;&lt;font face="&amp;#39;courier new&amp;#39;"&gt;&amp;nbsp;&amp;nbsp;from employee&lt;/font&gt;&lt;br&gt;&lt;div&gt;&lt;font face="&amp;#39;Courier New&amp;#39;"&gt;&amp;nbsp;&amp;nbsp;order by salary;&lt;/font&gt;&lt;/div&gt;&lt;br&gt;&lt;/div&gt;And the result set:&lt;br&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="ae:0"&gt;&lt;tbody&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;id&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;salary&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;dense_rank&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;rank&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;row_number&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;sum&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;8.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;9.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;5&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;12.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;5&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;5&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="16.666666666666668%"&gt;&lt;font size="2"&gt;5&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;As you see, the functions differs when repeated values are found in the order key (the salary of 10.00). With DENSE_RANK, no gaps are created and all repeated values receive the same counter. With RANK, the initial counter is used for all repeated values, but it make gaps so the next non-repeating value (the salary of 12.00) does not consider the previously repeated values as in different positions. With ROW_NUMBER, each line receives an incremental value. And SUM(1) is very like RANK, but the value is computed after all repeated values are summed, so the gap is before the repeated values.&lt;br&gt;&lt;br&gt;&lt;div&gt;&lt;b&gt;Navigational functions (LAG and LEAD):&lt;/b&gt;&amp;nbsp;with these functions, an expression could get the value of a previously (LAG) or a posterior (LEAD) row of the query. Follow the demonstrating query.&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;div&gt;select&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id,&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary,&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;lag(salary) over (order by salary),&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;lead(salary) over (order by salary)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;from employee&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;order by salary;&lt;/div&gt;&lt;br&gt;And the result set:&lt;/div&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="l7bi"&gt;&lt;tbody&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;id&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;salary&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;lag&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;lead&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;8.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;&amp;lt;null&amp;gt;&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;9.00&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;9.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;8.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;9.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;5&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;12.00&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align:left"&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;12.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td style="text-align:right" width="25%"&gt;&lt;font size="2"&gt;&amp;lt;null&amp;gt;&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;The functions have a second argument, that is implicitly 1, which means the number of previously/posterior rows will be queried. If this row does not exist, &amp;lt;null&amp;gt; is returned.&lt;br&gt;&lt;br&gt;&lt;div&gt;And of course, you can use these functions as expressions and compute, for example, the difference of an employee salary from the one greater and/or lesser.&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-3047828375655271072?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/3047828375655271072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=3047828375655271072&amp;isPopup=true' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/3047828375655271072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/3047828375655271072'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/02/window-functions-part3-new-functions.html' title='Window functions (part3) - new functions'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-1042376308171930577</id><published>2010-02-13T23:28:00.004-02:00</published><updated>2010-02-14T01:16:05.434-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Firebird History in 9 minutes video</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;This is a &lt;a href="http://vis.cs.ucdavis.edu/~ogawa/codeswarm/" target="_blank"&gt;code_swarm&lt;/a&gt; of the &lt;a href="http://firebird.cvs.sourceforge.net/firebird/firebird2/" target="_blank"&gt;firebird2&lt;/a&gt; tree.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/c97fRd3cBn0&amp;amp;hl=pt_BR&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/c97fRd3cBn0&amp;amp;hl=pt_BR&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-1042376308171930577?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/1042376308171930577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=1042376308171930577&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/1042376308171930577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/1042376308171930577'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/02/firebird-history-in-9-minutes-video.html' title='Firebird History in 9 minutes video'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-4648736804330735798</id><published>2010-01-24T16:59:00.001-02:00</published><updated>2010-01-24T17:00:16.688-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Window Functions (part2) - cumulative aggregates</title><content type='html'>Continuing with the &lt;a id="hwz5" href="http://asfernandes.blogspot.com/2010/01/window-functions_19.html" title="window function support for Firebird 3"&gt;window functions support for Firebird 3&lt;/a&gt;, I have now added another &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER&lt;/font&gt;&amp;nbsp;sub-clause: &lt;font class="Apple-style-span" face="'Courier New'"&gt;ORDER BY&lt;/font&gt;. The&amp;nbsp;&lt;font class="Apple-style-span" face="'Courier New'"&gt;ORDER BY&lt;/font&gt;&amp;nbsp;sub-clause can be used with or without partitions, and it makes aggregate functions return the partial aggregations as the records are being processed.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Considering our employee table has this data:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="aa_l" cellpadding="3" cellspacing="0" border="1" class="" bordercolor="#000000"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="50%" style="text-align: right;"&gt;id&lt;/td&gt;&lt;td width="50%" style="text-align: right;"&gt;salary&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%" style="text-align: right;"&gt;1&lt;/td&gt;&lt;td width="50%" style="text-align: right;"&gt;10.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%" style="text-align: right;"&gt;2&lt;/td&gt;&lt;td width="50%" style="text-align: right;"&gt;12.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%" style="text-align: right;"&gt;3&lt;/td&gt;&lt;td width="50%" style="text-align: right;"&gt;8.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%" style="text-align: right;"&gt;4&lt;/td&gt;&lt;td width="50%" style="text-align: right;"&gt;9.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%" style="text-align: right;"&gt;5&lt;/td&gt;&lt;td width="50%" style="text-align: right;"&gt;10.00&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;And we run this query:&lt;div&gt;&lt;br&gt;&lt;span style="font-family: 'Courier New'"&gt;select&lt;br&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id, salary, sum(salary) over (order by salary) cum_salary&lt;br&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;from employee&lt;/span&gt;&lt;br&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;order by salary;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;The result set produced will be:&lt;div&gt;&lt;br&gt;&lt;div&gt;&lt;div&gt;&lt;table id="nav." cellpadding="3" cellspacing="0" border="1" class="" bordercolor="#000000"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;id&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;salary&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;cum_salary&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;3&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;8.00&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;8.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;4&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;9.00&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;17.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;1&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;10.00&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;37.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;5&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;10.00&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;37.00&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;2&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;12.00&lt;/td&gt;&lt;td width="33.333333333333336%" style="text-align: right;"&gt;49.00&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;So cum_salary returns the partial/accumulated aggregation (of the &lt;font class="Apple-style-span" face="'Courier New'"&gt;SUM&lt;/font&gt; function). You may found strange the 37.00 repeated for the ids 1 and 5, but that is how it should work. The &lt;font class="Apple-style-span" face="'Courier New'"&gt;ORDER BY&lt;/font&gt; keys are grouped together and the aggregation is computed once (but summing the two 10.00).&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;You can use multiple windows with different orders, and &lt;font class="Apple-style-span" face="'Courier New'"&gt;ORDER BY&lt;/font&gt; parts like &lt;font class="Apple-style-span" face="'Courier New'"&gt;DESC&lt;/font&gt;,&lt;font class="Apple-style-span" face="'Courier New'"&gt; NULLS LAST&lt;/font&gt;, etc. Here is a weird example:&lt;/div&gt;&lt;br&gt;&lt;span style="font-family: 'Courier New'"&gt;&lt;div&gt;&lt;/div&gt;select&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id, salary,&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sum(salary) over (order by salary) cum_salary,&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sum(salary) over (order by salary desc) cum_salary_desc&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;from employee&lt;/span&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;order by salary;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;font size="2"&gt;The result set produced will be:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="c33t" cellpadding="3" cellspacing="0" border="1" class="" bordercolor="#000000"&gt;&lt;tbody&gt;&lt;tr style="text-align: left"&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;id&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;salary&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;cum_salary&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;cum_salary_desc&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align: left"&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;3&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;8.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;8.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;49.00&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align: left"&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;4&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;9.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;17.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;41.00&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align: left"&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;1&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;37.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;32.00&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align: left"&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;5&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;10.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;37.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;32.00&lt;/td&gt;&lt;/tr&gt;&lt;tr style="text-align: left"&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;2&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="2"&gt;12.00&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;49.00&lt;/font&gt;&lt;br&gt;&lt;/font&gt;&lt;/td&gt;&lt;td width="25%" style="text-align: right;"&gt;12.00&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;With a partition&amp;nbsp;&lt;font class="Apple-style-span" face="'Courier New'"&gt;ORDER BY&lt;/font&gt; works the same way, but at each partition boundary the aggregation is reset.&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;All aggregation functions are usable with &lt;font class="Apple-style-span" face="'Courier New'"&gt;ORDER BY&lt;/font&gt;, except the &lt;font class="Apple-style-span" face="'Courier New'"&gt;LIST&lt;/font&gt; function. As &lt;font class="Apple-style-span" face="'Courier New'"&gt;LIST&lt;/font&gt; returns blob, it would be slow to return multiple blobs (one for each order group), trick to implement, and I don't see an usage scenario for it.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-4648736804330735798?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/4648736804330735798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=4648736804330735798&amp;isPopup=true' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/4648736804330735798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/4648736804330735798'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/01/window-functions-part2-cumulative_24.html' title='Window Functions (part2) - cumulative aggregates'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-1376567073563113433</id><published>2010-01-19T00:29:00.001-02:00</published><updated>2010-01-19T00:29:44.456-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Window Functions</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;font size="2"&gt;By the SQL specification, &lt;i&gt;window functions&lt;/i&gt; are a kind of aggregation, but which does not “filter” the result set of a query. The aggregated data is mixed with the query result set. That sort of functions are used with the &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER&lt;/font&gt; clause. Users of Oracle also knows window functions as analytical functions.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;We have promissed very basic support for window functions in Firebird 3, which was the &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER ()&lt;/font&gt; clause using the current aggregate functions. With the &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER ()&lt;/font&gt; clause, one can mix with the query result set the aggregated data over the entire result set. Let me explain with an example.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;We have a table EMPLOYEE with columns ID, NAME and SALARY, and want to show each employee with his respective salary and the percentage of his salary over the payroll. With a “normal” query, we would do:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;select&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;name,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary / (select sum(salary) from employee) percentage&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;from employee;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;We need to repeat ourselves and wait so much to see the results. We can also make it hopefully faster using a cross join, but still the whole employee table will need to be read more than one time. Change the table by a complex view or add various “windows” and we'll have a performance problem for sure.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;The same query could be specified in much more elegant and faster way using a window function. Here is it how:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;select&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;name,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary / sum(salary) over () percentage&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;from employee;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;Here, &lt;font class="Apple-style-span" face="'Courier New'"&gt;sum(salary) over ()&lt;/font&gt; is computed with the sum of all SALARY from the query (the employee table). This is what the &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER ()&lt;/font&gt; clause does.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;But the &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER&lt;/font&gt; clause is not just that, and now I've added another of its subclauses to Firebird. It's the &lt;font class="Apple-style-span" face="'Courier New'"&gt;PARTITION&lt;/font&gt; subclause.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;A partition is a way to make the &lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER&lt;/font&gt; aggregation based on a GROUP. Its syntax is:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;lt;window function&amp;gt;([&amp;lt;expr&amp;gt;]) OVER (PARTITION BY &amp;lt;expr&amp;gt; [, &amp;lt;expr&amp;gt; ...])&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;So now since the aggregation is done over a group, it could produce more than one row. So the result set generated by a partition is joined with the main query using the same expression list of the partition.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;For a example, lets add to our employee table a ROLE column. Now we want the same information, but instead of see the percentage of the employee salary over all employees, we want to see that value based on the employees occuping the same role. Here is how that query could be written:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;select&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;id,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;name,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;role,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary,&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;salary / sum(salary) over (partition by role)&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;from employee;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;With the current implementation, the query (without the window functions) is executed one time and cached. Extra aggregation is done on this cached data. Partitions are joined by the new hash join algorithmn, and the main window (&lt;font class="Apple-style-span" face="'Courier New'"&gt;OVER&lt;/font&gt; without a partition) is joined through a cross join with the main query.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;There is much more about window functions, but this subset seems to cover some major use cases of them.&lt;/font&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-1376567073563113433?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/1376567073563113433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=1376567073563113433&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/1376567073563113433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/1376567073563113433'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2010/01/window-functions_19.html' title='Window Functions'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-6659982227880417948</id><published>2009-12-10T22:11:00.001-02:00</published><updated>2009-12-10T22:44:03.124-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Integração da JVM ao Firebird</title><content type='html'>&lt;div&gt;A um tempo atrás "descobri" a integração do Oracle com Java no lado servidor, e logo pensei: O Firebird precisa disso também.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Sabia da iniciativa anterior de outros desenvolvedores fazerem o mesmo, e a idéia foi fazer o projeto vingar. Por diversos motivos isso pareceu impossível, então resolvi iniciar uma implementação alternativa (o&amp;nbsp;&lt;a id="zetb" href="http://www.firebirdsql.org/index.php?op=devel&amp;amp;sub=plugins&amp;amp;id=external_java" title="FB/Java"&gt;FB/Java&lt;/a&gt;), bastante diferente internamente e com mais recursos (inclusive que o Oracle).&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Usei este projeto como trabalho de conclusão de curso (TCC) de Ciência da Computação, e estou disponibilizando o mesmo para &lt;a id="s6fy" href="https://docs.google.com/uc?export=download&amp;amp;id=0B2HKd9p4kWe-Mzk5MDU4ODQtMDE4Zi00YWIzLWI2NDctOWNiMzg0ZTM3ZTI3" title="download"&gt;download&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Inicio explicando os conceitos e funcionalidades do Firebird e do Java relevantes ao tema. Depois, explico o funcionamento da integração entre as duas tecnologias.&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-6659982227880417948?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/6659982227880417948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=6659982227880417948&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6659982227880417948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6659982227880417948'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2009/12/integracao-da-jvm-ao-firebird.html' title='Integração da JVM ao Firebird'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-2780905600062027684</id><published>2009-11-02T14:44:00.001-02:00</published><updated>2009-11-02T14:44:33.233-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Ubuntu 9.10 review</title><content type='html'>I've upgraded Ubuntu 9.04 to 9.10, and here is what I found about it.&lt;br&gt;&lt;br&gt;At upgrade start, it asked about keyboard. Surprisingly, it has nothing about Brazilian keyboards and I choose to maintain "kernel keymaps" without know what exactly that is and why that keyboard popup appeared.&lt;br&gt;&lt;br&gt;During the upgrade, flash_plugin and package_hook updates crashed. Nvidia driver, as always failed too. So after restarting in safe mode, I changed nvidia driver to nv to be able to enter in the graphical mode.&lt;br&gt;&lt;br&gt;Then, to fix the system:&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sudo aptitude safe-upgrade&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sudo aptitude safe-upgrade&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sudo aptitude dist-upgrade&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br&gt;And reverted to nvidia driver.&lt;br&gt;&lt;br&gt;They claim to have new beautiful and faster boot. Lies. The new boot screen is horrible, specially when running fsck. And appears to be slower than in 9.04.&lt;br&gt;&lt;br&gt;The "fast user switch" gnome applet do not exist as before. It can't show your IM status anymore, nor can be compact as before. I changed it by the shutdown applet to have the same functionality that I used to have.&lt;br&gt;&lt;br&gt;As with Ubuntu 9.04, Firefox 3.5 continues slow as the 9.04 Shiretoko in my system. And the flash plugin continue crashing. I use the AMD64 version, which requires wrapper to 32 bit flash, because Adobe didn't released the final AMD64 version yet.&lt;br&gt;&lt;br&gt;Resuming, you decide. I want an updated system anyway. :-) &lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-2780905600062027684?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/2780905600062027684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=2780905600062027684&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/2780905600062027684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/2780905600062027684'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2009/11/ubuntu-910-review.html' title='Ubuntu 9.10 review'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-4365531497178905485</id><published>2009-08-09T12:45:00.001-03:00</published><updated>2009-08-09T12:46:03.823-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>The buggy const</title><content type='html'>In C/C++, there are constants and pointer to constants. I'm talking here about constants (i.e., &lt;span style="font-family: Courier New;"&gt;const int var1; int* const var2&lt;/span&gt;) and not pointer to constants (i.e., &lt;span style="font-family: Courier New;"&gt;const int* var3&lt;/span&gt;).&lt;br&gt;&lt;br&gt;In 90% of cases that I see, usage of constants for &lt;b&gt;local "variables" and parameters&lt;/b&gt; is "wrong". People seems to use it for a variable that is not changing, while, in my opinion, it should rather be used for variables that should never change.&lt;br&gt;&lt;br&gt;Anyway, I always thought that constant parameters were not part of function signatures, because a const parameter has nothing to do with the caller, but is routine implementation detail. Indeed, this code compiles, links and run with G++ and MSVC++ and is also validated by the &lt;a title="Comeau online validator" target="_blank" href="http://www.comeaucomputing.com/tryitout/" id="m18x"&gt;Comeau online validator&lt;/a&gt;:&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;class Test&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;public:&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void m1(const int n);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void m2(int n);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;};&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;int main()&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Test t;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;t.m1(10);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;t.m2(10);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return 0;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;void Test::m1(int n)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;printf("%d\n", n);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;void Test::m2(const int n)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;printf("%d\n", n);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br&gt;&lt;/div&gt;But not all compilers agree. It has been sent some patches fixing these inconsistencies to compile Firebird with Solaris Sun Studio compiler. This usage seems to cause problems because the compiler treat the declaration and implementation as different signatures.&lt;br&gt;&lt;br&gt;In Java, &lt;b style="font-family: Courier New;"&gt;final&lt;/b&gt; could be used for the same thing. Let see what it think about:&lt;br&gt;&lt;div style="margin-left: 40px; font-family: Courier New;"&gt;&lt;br&gt;interface Int&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void m1(final int n);&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void m2(int n);&lt;br&gt;}&lt;br&gt;&lt;br&gt;class Test implements Int&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void m1(int n)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void m2(final int n)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;div style="font-family: Courier New;"&gt;&lt;font face="Verdana"&gt;Java also accepts this code.&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-4365531497178905485?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/4365531497178905485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=4365531497178905485&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/4365531497178905485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/4365531497178905485'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2009/08/buggy-const.html' title='The buggy const'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-343028017659761590</id><published>2009-08-08T19:17:00.001-03:00</published><updated>2009-08-09T12:10:35.267-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>DDL execution architecture in Firebird - why we need to move on</title><content type='html'>Here I'm going to explain how Firebird DDL commands works in the architecture, why it stops innovation and how it is supposed to work in Firebird 3.0.&lt;br&gt;&lt;br&gt; DDL in FB works more or less like DML, so first a briefly explanation of how DML works. When a DML command is prepared, it starts in the parser constructing a tree of nodes. That nodes are all a single pointer type, used for all node types and others usages (like storing constants). A node have a list of child nodes.&lt;br&gt;&lt;br&gt; After parsing, it enters in the semantics phase, where things are verified and adjusted with execution in mind. After that, it enters in the generation phase, that outputs BLR bytes and stores them in the statement. &lt;br&gt;&lt;br&gt; The DSQL API is a layer around the engine API. The engine API knows only how to execute BLR. Hence the DSQL API does passes the stored BLR to that lower level functions (engine API).&lt;br&gt;&lt;br&gt; For engine API, there is no knowledge of DSQL nodes and the processing done in the semantics phase. The engine does a parse of BLR, reconstruct another tree and compiles it. That does almost what DSQL does, but DSQL does it on SQL code and engine does it on BLR bytes.&lt;br&gt;&lt;br&gt; When a statement is executed, the BLR tree is traversed and everything runs.&lt;br&gt;&lt;br&gt; So back to DDL... DDL is not described as BLR, but in an equivalent binary format: DYN. Some DYN verbs have BLR bytes embedded, like the body of a stored procedure, but that is not relevant for generic DDL handling.&lt;br&gt;&lt;br&gt; As in DML case, the engine knows nothing about DDL nodes constructed in DSQL. The engine knows only how to run DYN, with the isc_ddl API. In DSQL, everything works as in DML, but the generation phase emits DYN bytes, and statement execution is layered around isc_ddl.&lt;br&gt;&lt;br&gt; So you might ask, what's wrong with DDL execution if it's so consistent with DML?&lt;br&gt;&lt;br&gt; A lot of things, I'd say:&lt;br&gt; &lt;br&gt;&lt;ul&gt;&lt;li&gt; DYN codes are very badly structured. Some codes that would be private for some specific verbs shares the "number space" of all verbs. That make things visible wrong. &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Related to above, we're going out of space. In v2.5, we're at number 247. We could go only at 254, and use the 255 to make a second number space. This would make things even worse. &lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;While some may say that BLR is also bad, this is a model not invented in InterBase/Firebird. This is how compilers works (assembly, byte codes, etc). But that model does not have any practical benefit in DDL.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Too much code is used to convert DSQL structures to bytes and to engine again.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;There is large code duplication to handle similar things, like CREATE / ALTER commands.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;DYN execution is totally unnatural for a RDBMS system. A CREATE PROCEDURE command is more or less defined this way: &lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt; &lt;br&gt;&lt;div style="margin-left: 40px;"&gt; &lt;span style="font-family: Courier New;"&gt;isc_dyn_def_procedure, &amp;lt;name&amp;gt;,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_prc_source, &amp;lt;source&amp;gt;,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; ...,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; // for each parameter - begin&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_def_parameter, &amp;lt;name&amp;gt;,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_prm_number, &amp;lt;number&amp;gt;,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_prm_type, &amp;lt;type&amp;gt;,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; ...,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_end,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; // for each parameter - end&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_prc_blr, &amp;lt;bytes&amp;gt;,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; isc_dyn_end&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;/div&gt; &lt;br&gt;&lt;div style="margin-left: 40px;"&gt; And is executed in this way (pseudo-code):&lt;br&gt;&lt;br&gt;&lt;/div&gt;  &lt;div style="margin-left: 80px;"&gt;&lt;span style="font-family: Courier New;"&gt;function DYN_execute() &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while ((dynVerb = getDynByte()) != isc_dyn_end) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{ &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;switch (dynVerb) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;{ &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;case isc_dyn_def_procedure: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DYN_define_procedure(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;case isc_dyn_def_parameter: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;DYN_define_parameter(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;break; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ... &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;} &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;} &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; function DYN_define_procedure() &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procName = getString(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ((dynVerb = getDynByte()) != isc_dyn_end) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;switch (dynVerb) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case isc_dyn_prc_source: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; procSource = getString(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case isc_dyn_prc_blr: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; procBlr = getBytes(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ... &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DYN_execute(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT INTO RDB$PROCEDURES &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; } &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; function DYN_define_parameter() &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;     &amp;nbsp;&amp;nbsp; &amp;nbsp;paramName = getString(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ((dynVerb = getDynByte()) != isc_dyn_end) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch (dynVerb) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case isc_dyn_prm_number: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;paramNumber = getNumber(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case isc_dyn_prm_type: &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; paramType = getParamType(); &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT INTO RDB$PROCEDURE_PARAMETERS &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt; } &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;/div&gt;       &lt;div style="margin-left: 40px;"&gt;&lt;br&gt; Did you see what is wrong? Did you ever asked why Firebird system tables does not have primary and foreign keys?&lt;br&gt;&lt;br&gt; The answer is simple, there is no way to have a FK from RDB$PROCEDURE_PARAMETERS to RDB$PROCEDURES if the records in RDB$PROCEDURE_PARAMETERS are inserted first.&lt;br&gt;&lt;/div&gt; &lt;br&gt; With these problems defined, I started an alternate DDL path in v2.5, with the ALTER CHARACTER SET command. This command does not emit DYN, and when asked to execute, it does execute directly in DSQL with a new C++ friendly node (also used in the parser).&lt;br&gt;&lt;br&gt; This was not sufficient through. To have benefits, existing commands shall also be migrated to the new scheme, and DYN should better be totally eliminated. The problem of this is that, documented or not, DYN and isc_ddl are part of the API, and used by client tools. The GDEF utility is totally based on it, as well DDL commands of GPRE.&lt;br&gt;&lt;br&gt; These archaic utilities are the reason of how things had been defined in this way and why it never changed. Natively, former InterBase versions didn't understand text commands. DDL and DML had been part of client utilities, that compiles them and send BLR/DYN to the server.&lt;br&gt;&lt;br&gt; Fortunately the Firebird team agreed to deprecate (in the sense of warn to tell to not use anymore) these things in v2.5, so it will be eliminated in v3.0.&lt;br&gt;&lt;br&gt; &lt;a href="http://firebird.cvs.sourceforge.net/viewvc/firebird/firebird2/?pathrev=B2_5_ExtEngines"&gt;In my branch for v3.0&lt;/a&gt;, I started to implement this conversion. Procedures and triggers had been refactored and their DYN handling was eliminated. The new external function was also done in the new scheme. With nice C++ classes, the architecture of PACKAGES became smooth. Also, the implementation of these commands became shorter, self-contained and much more readable.&lt;br&gt;&lt;br&gt; Yesterday, I did a step further and did some unification of EXECUTE BLOCK (DML) with procedures and triggers (DDL) code. A prototype of sub-procedures is in the way...&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-343028017659761590?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/343028017659761590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=343028017659761590&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/343028017659761590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/343028017659761590'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2009/08/ddl-execution-architecture-in-firebird_4841.html' title='DDL execution architecture in Firebird - why we need to move on'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-6883764296852482659</id><published>2009-08-02T20:45:00.001-03:00</published><updated>2009-08-02T22:33:48.061-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>CVSNT client is slow</title><content type='html'>For years I was using CVSNT client to work with Firebird and any other CVS repository. I started to use it because I needed a client capable of handling the "sserver" protocol method, which the "standard" CVS can't.&lt;br&gt;&lt;br&gt;A first thing I've noted has that it most times refetches completely (or just crashes trying) Firebird ChangeLog file during updates because some "corruption" (supposedly because it has more than 2MB). But that was OK with me, I just press Ctrl+Break and continue working.&lt;br&gt;&lt;br&gt;By some reason, I had to use Cygwin's CVS to checkout whole firebird2 tree. It was &lt;b&gt;much faster&lt;/b&gt;. So I switched to non-NT client and anything is much faster with it.&lt;br&gt;&lt;br&gt;I've just started a merge of HEAD in my branch now. A lot of conflicts to resolve, most of them related to cleanups and formating changes. Unfortunately, it can't make this faster. :-)&lt;br&gt;&lt;br&gt;BTW1, to open all conflicted files in gedit, I'm using:&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;b style="font-family: Courier New;"&gt;grep -RlZ "&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;" builds/ src/ |xargs -0 gedit&lt;/b&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;BTW2, CVS is dead. Who cares?&lt;br&gt;&lt;br&gt;BTW3, GIT seems excellent, but is somewhat difficult to grasp.&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-6883764296852482659?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/6883764296852482659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=6883764296852482659&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6883764296852482659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/6883764296852482659'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2009/08/cvsnt-client-is-slow.html' title='CVSNT client is slow'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3443854162607009076.post-7484951659587315675</id><published>2009-07-12T23:25:00.001-03:00</published><updated>2009-07-14T22:35:29.360-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firebird'/><title type='text'>Influence of network latency in the Firebird wire protocol</title><content type='html'>People often talk that Firebird performs badly in networks with high latency. I did some tests to see how the new protocol has been improved compared to the old one, and to see how it could be improved even more. My tests only cares about &lt;b&gt;latency&lt;/b&gt;, and not about bandwidth.&lt;br&gt;&lt;br&gt;It simulate network latency in Linux using &lt;a title="Netem" href="http://www.linuxfoundation.org/en/Net:Netem" id="bc1w"&gt;Netem&lt;/a&gt;. With the &lt;i&gt;tc&lt;/i&gt; utility, we can add a delay for outbound traffic. Since I did it for &lt;i&gt;lo&lt;/i&gt; interface, it happens that it works for in/out traffic. I set delay to 100ms (that is more or less a value I found doing it in the internet with my horrible Telefonica &lt;strike&gt;speed&lt;/strike&gt;y connection), using this command:&lt;br&gt;&lt;div style="margin-left: 40px; font-family: Courier New; text-align: left;"&gt;&lt;b&gt;$ sudo tc qdisc add dev lo root handle 1:0 netem delay 100ms&lt;br&gt;&lt;/b&gt;&lt;/div&gt;&lt;br&gt;And here is the result of a &lt;i&gt;ping&lt;/i&gt;:&lt;br&gt;&lt;div style="margin-left: 40px; font-family: Courier New; text-align: left;"&gt;&lt;b&gt;$ ping localhost&lt;br&gt;&lt;/b&gt;PING localhost (127.0.0.1) 56(84) bytes of data.&lt;br&gt;64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=200 ms&lt;br&gt;64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=200 ms&lt;br&gt;64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=200 ms&lt;br&gt;64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=200 ms&lt;br&gt;&lt;/div&gt;&lt;br&gt;To later remove the delay, the command is:&lt;br&gt;&lt;div style="margin-left: 40px; text-align: left;"&gt;&lt;b&gt;&lt;span style="font-family: Courier New;"&gt;$ sudo tc qdisc del dev lo root&lt;/span&gt;&lt;br&gt;&lt;/b&gt;&lt;/div&gt;&lt;br&gt;The test uses &lt;a title="Firebird library" href="http://code.google.com/p/cppsys/source/browse/#svn/trunk/src/CppSys/Database/Firebird" id="gdng"&gt;Firebird library&lt;/a&gt; present on (my till unknown) &lt;a title="CppSys" href="http://code.google.com/p/cppsys" id="vipk"&gt;CppSys&lt;/a&gt; project (more on CppSys in a future post). The CppSys database library has interfaces and semantics based on JDBC. The relevant test code is here:&lt;br&gt;&lt;div style="margin-left: 40px; text-align: left;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Connecting to the database");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;AutoPtr&amp;lt;FbDatabase&amp;gt; database(client-&amp;gt;openDatabase(&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;String("firebird:") + databaseName));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Starting the transaction");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;AutoPtr&amp;lt;FbTransaction&amp;gt; transaction(database-&amp;gt;startTransaction(&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;TransactionIsolation::SNAPSHOT));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Preparing stmt1");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;AutoPtr&amp;lt;FbPreparedStatement&amp;gt; stmt1(database-&amp;gt;prepareStatement(&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;transaction,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"select rdb$relation_name from rdb$relations"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"&amp;nbsp;&amp;nbsp; &amp;nbsp;where rdb$system_flag = 1"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"&amp;nbsp;&amp;nbsp; &amp;nbsp;order by rdb$relation_name"));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Preparing stmt2");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;AutoPtr&amp;lt;FbPreparedStatement&amp;gt; stmt2(database-&amp;gt;prepareStatement(&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;transaction,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"select rdb$field_name from rdb$relation_fields"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"&amp;nbsp;&amp;nbsp; &amp;nbsp;where rdb$relation_name = ?"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"&amp;nbsp;&amp;nbsp; &amp;nbsp;order by rdb$field_name"));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Preparing stmt3");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;AutoPtr&amp;lt;FbPreparedStatement&amp;gt; stmt3(database-&amp;gt;prepareStatement(&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;transaction,&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"select rdb$trigger_name from rdb$triggers"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"&amp;nbsp;&amp;nbsp; &amp;nbsp;where rdb$relation_name = ?"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"&amp;nbsp;&amp;nbsp; &amp;nbsp;order by rdb$trigger_name"));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Executing stmt1");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;AutoPtr&amp;lt;FbResultSet&amp;gt; rs1(stmt1-&amp;gt;executeQuery());&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;println("Starting fetch rs1");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;while (rs1-&amp;gt;fetch())&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("rs1: %s", rs1-&amp;gt;getString(1).getPtr());&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("\tExecuting stmt2");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;stmt2-&amp;gt;setString(1, rs1-&amp;gt;getString(1));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;AutoPtr&amp;lt;FbResultSet&amp;gt; rs2(stmt2-&amp;gt;executeQuery());&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("\tExecuting stmt3");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;stmt3-&amp;gt;setString(1, rs1-&amp;gt;getString(1));&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;AutoPtr&amp;lt;FbResultSet&amp;gt; rs3(stmt3-&amp;gt;executeQuery());&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("\tStarting fetch rs2");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (rs2-&amp;gt;fetch())&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("\trs2: %s", rs2-&amp;gt;getString(1).getPtr());&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("\tStarting fetch rs3");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (rs3-&amp;gt;fetch())&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;println("\trs3: %s", rs3-&amp;gt;getString(1).getPtr());&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;/div&gt;&lt;br&gt;&lt;span style="font-family: Verdana;"&gt;The &lt;/span&gt;&lt;font style="font-family: Verdana;" face="Courier New"&gt;&lt;span style="font-family: Courier New;"&gt;println&lt;/span&gt; function &lt;/font&gt;buffers the text and prints it in its next run, with the current time (in milliseconds) minus the time when the text was buffered. Here is its code:&lt;br&gt;&lt;div style="margin-left: 40px; text-align: left;"&gt;&lt;span style="font-family: Courier New;"&gt;static void println(const char* format, ...)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;static char lineBuffer[1024];&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;static int64 lastTime = 0;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;timeb tb;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ftime(&amp;amp;tb);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;int64 thisTime = int64(tb.time) * 1000 + tb.millitm;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (lastTime == 0)&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;lastTime = thisTime;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;printf("%06d: %s\n", (int) (thisTime - lastTime),&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;lineBuffer);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;va_list va;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;va_start(va, format);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;vsprintf(lineBuffer, format, va);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;va_end(va);&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;lastTime = thisTime;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;/div&gt;&lt;br&gt;As you see, the test does what every client/server database developer must knows that he/she shouldn't do: a main query with nested queries for each record. If you ever run ISQL over the internet, you had see it performs very slow, and that is the reason. ISQL does just that. It does that because it's written using embedded SQL with GPRE and sometimes this is needed to access new columns that may not be presented on a database of an older ODS. And due to embedded SQL nature, "details" of where and when to prepare statements are just ignored.&lt;br&gt;&lt;br&gt;So far, here is the results.&lt;br&gt;&lt;br&gt;Result for the &lt;b&gt;old protocol&lt;/b&gt;, with 2.0 client and 2.5 server:&lt;br&gt;&lt;div style="margin-left: 40px; text-align: left;"&gt;000665: Connecting to the database&lt;br&gt;000201: Starting the transaction&lt;br&gt;001234: Preparing stmt1&lt;br&gt;001204: Preparing stmt2&lt;br&gt;001204: Preparing stmt3&lt;br&gt;000200: Executing stmt1&lt;br&gt;000202: Starting fetch rs1&lt;br&gt;000000: rs1: MON$ATTACHMENTS&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt2&lt;br&gt;000201: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt3&lt;br&gt;000201: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$ATTACHMENT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$ATTACHMENT_NAME&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$CHARACTER_SET_ID&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$GARBAGE_COLLECTION&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_ADDRESS&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_PID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_PROCESS&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_PROTOCOL&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$ROLE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$SERVER_PID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STATE&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STAT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$TIMESTAMP&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$USER&lt;br&gt;000601: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs3&lt;br&gt;000000: rs1: MON$CALL_STACK&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt2&lt;br&gt;000201: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt3&lt;br&gt;000201: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$CALLER_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$CALL_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$OBJECT_NAME&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$OBJECT_TYPE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$SOURCE_COLUMN&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$SOURCE_LINE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STATEMENT_ID&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STAT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$TIMESTAMP&lt;br&gt;000601: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs3&lt;br&gt;&amp;lt;...&amp;gt;&lt;br&gt;000000: rs1: RDB$CHECK_CONSTRAINTS&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt2&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt3&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs2&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: RDB$CONSTRAINT_NAME&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: RDB$TRIGGER_NAME&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs3&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_14&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_15&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_16&lt;br&gt;000400: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_35&lt;br&gt;000000: rs1: RDB$COLLATIONS&lt;br&gt;&amp;lt;...&amp;gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Result for the &lt;b&gt;new protocol&lt;/b&gt;, with 2.5 client and 2.5 server:&lt;br&gt;&lt;div style="margin-left: 40px; text-align: left;"&gt;000670: Connecting to the database&lt;br&gt;000200: Starting the transaction&lt;br&gt;000229: Preparing stmt1&lt;br&gt;000203: Preparing stmt2&lt;br&gt;000203: Preparing stmt3&lt;br&gt;000000: Executing stmt1&lt;br&gt;000202: Starting fetch rs1&lt;br&gt;000000: rs1: MON$ATTACHMENTS&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt3&lt;br&gt;000202: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$ATTACHMENT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$ATTACHMENT_NAME&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$CHARACTER_SET_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$GARBAGE_COLLECTION&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_ADDRESS&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_PID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_PROCESS&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$REMOTE_PROTOCOL&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$ROLE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$SERVER_PID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STATE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STAT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$TIMESTAMP&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$USER&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs3&lt;br&gt;000000: rs1: MON$CALL_STACK&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt3&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$CALLER_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$CALL_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$OBJECT_NAME&lt;br&gt;000001: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$OBJECT_TYPE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$SOURCE_COLUMN&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$SOURCE_LINE&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STATEMENT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$STAT_ID&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: MON$TIMESTAMP&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs3&lt;br&gt;&amp;lt;...&amp;gt;&lt;br&gt;000000: rs1: RDB$CHECK_CONSTRAINTS&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;Executing stmt3&lt;br&gt;000201: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs2&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: RDB$CONSTRAINT_NAME&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs2: RDB$TRIGGER_NAME&lt;br&gt;000200: &amp;nbsp;&amp;nbsp; &amp;nbsp;Starting fetch rs3&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_14&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_15&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_16&lt;br&gt;000000: &amp;nbsp;&amp;nbsp; &amp;nbsp;rs3: RDB$TRIGGER_35&lt;br&gt;000000: rs1: RDB$COLLATIONS&lt;br&gt;&amp;lt;...&amp;gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;FWIW, I did tested the old protocol on real network with similar latency too. The result was very resemblant.&lt;br&gt;&lt;br&gt;The total times are:&lt;br&gt;&lt;div&gt;&lt;table class="" id="kc6t" border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" height="89" width="339"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Old protocol&lt;br&gt;&lt;/td&gt;&lt;td align="right"&gt;55.5s&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;New Protocol&lt;br&gt;&lt;/td&gt;&lt;td align="right"&gt;18.5s&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;New Protocol minus round-trip times of rs3&lt;br&gt;&lt;/td&gt;&lt;td align="right"&gt;10.1s&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br&gt;So we may see that:&lt;br&gt;1) The old protocol is a crap.&lt;br&gt;2) The new protocol does a good job removing some "unnecessary" round-trips.&lt;br&gt;3) It may be improved.&lt;br&gt;&lt;br&gt;The first interesting problem is the series of statement preparations. The preparation of a statement may result in an error, so it necessary involves a round-trip so we can get the status from the server. But does it &lt;b&gt;really needs&lt;/b&gt; it? Using Oracle JDBC driver, a prepareStatement with a wrong statement does not throw an exception. It's deferred. In fact, this is a contract, and a change in a contract would require some way for the client applications to enable or disable it.&lt;br&gt;&lt;br&gt;The second interesting thing is that executing a statement that needs fetch does not involves a round-trip. Does it happens too when selecting from a SP? Won't this be a contract change as well, since selectable SPs could write to the database? I didn't did further tests... Anyway, that's what allows the optimizations I talk below.&lt;br&gt;&lt;br&gt;Then we start the fetches. The first fetch for rs1 necessarily involves a round-trip and buffers some records in the client. Subsequents fetches are resolved locally.&lt;br&gt;&lt;br&gt;The third interesting thing is about the nested queries. Since queries are executed, a round-trip would be inevitable, but it does one for each query. A more intelligent approach would be to fetch rs3 too when asked to fetch rs2, since it's already executed. In this test, it would run ~8s faster. And a much more intelligent approach would do it in the background (and transmitting asynchronous), without putting some overhead on the rs2 call.&lt;br&gt;&lt;br&gt;With a super intelligent server/client/protocol, the client and the server may cache prepared statements, and the server may asynchronous send statements invalidations to the client. Then, preparation of statements would have no round-trip (when already prepared one time), being sure that the statement is not wrong.&lt;br&gt;&lt;br&gt;So what you may do now?&lt;br&gt;1) Do not talk with the server in this poor (and common) way. Use selectable SPs to run multiple queries.&lt;br&gt;2) Do not prepare/close/prepare your common statements. Cache them in your application.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3443854162607009076-7484951659587315675?l=asfernandes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asfernandes.blogspot.com/feeds/7484951659587315675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3443854162607009076&amp;postID=7484951659587315675&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/7484951659587315675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3443854162607009076/posts/default/7484951659587315675'/><link rel='alternate' type='text/html' href='http://asfernandes.blogspot.com/2009/07/network-latency-influence-on-firebird.html' title='Influence of network latency in the Firebird wire protocol'/><author><name>Adriano dos Santos Fernandes</name><uri>https://profiles.google.com/110919600889106217615</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-tD0YsCkOO_Y/AAAAAAAAAAI/AAAAAAAAAF0/bRnXuFCv-Cc/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry></feed>
