<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="cs">
	<id>http://postgres.cz/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=130.225.61.3</id>
	<title>PostgreSQL - Příspěvky [cs]</title>
	<link rel="self" type="application/atom+xml" href="http://postgres.cz/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=130.225.61.3"/>
	<link rel="alternate" type="text/html" href="http://postgres.cz/wiki/Speci%C3%A1ln%C3%AD:P%C5%99%C3%ADsp%C4%9Bvky/130.225.61.3"/>
	<updated>2026-07-04T11:52:31Z</updated>
	<subtitle>Příspěvky</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>http://postgres.cz/index.php?title=Polymorfn%C3%AD_funkce_quote_literal&amp;diff=372</id>
		<title>Polymorfní funkce quote literal</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=Polymorfn%C3%AD_funkce_quote_literal&amp;diff=372"/>
		<updated>2007-11-26T09:42:08Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tento zdrojový kód je ukázkou polymorfní SPI funkce (polymorfní - její parametr je typu ANYELEMENT, SPI - Server Programming Interface). Funkčnost této funkce je stejná jako u vestavěné funkce quote_literal. Rozdíl je v parametrech. Zatímco parametr vestavěné funkce je typu TEXT (přetypování na tento typ zajistí systém), parametr funkce z příkladu je ANYELEMENT, a funkce sama  musí zajistit korektní přetypování. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;executor/spi.h&amp;quot;               /* this is what you need to work with SPI */&lt;br /&gt;
#include &amp;quot;utils/lsyscache.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PG_MODULE_MAGIC;&lt;br /&gt;
&lt;br /&gt;
extern Datum quote_literal(PG_FUNCTION_ARGS);&lt;br /&gt;
PG_FUNCTION_INFO_V1(quote_literal);&lt;br /&gt;
&lt;br /&gt;
Datum&lt;br /&gt;
quote_literal(PG_FUNCTION_ARGS)&lt;br /&gt;
{&lt;br /&gt;
        text *result;&lt;br /&gt;
        Oid         valtype = get_fn_expr_argtype(fcinfo-&amp;gt;flinfo, 0);&lt;br /&gt;
        Datum       value = PG_GETARG_DATUM(0);&lt;br /&gt;
        Oid                     typoutput;&lt;br /&gt;
        bool            typIsVarlena;&lt;br /&gt;
        StringInfoData buf;&lt;br /&gt;
&lt;br /&gt;
        if (!OidIsValid(valtype))&lt;br /&gt;
                elog(ERROR, &amp;quot;could not determine data type of input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        initStringInfo(&amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        appendStringInfoChar(&amp;amp;buf, &#039;\&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
        getTypeOutputInfo(valtype, &amp;amp;typoutput, &amp;amp;typIsVarlena);&lt;br /&gt;
        appendStringInfoString(&amp;amp;buf, OidOutputFunctionCall(typoutput, value));&lt;br /&gt;
&lt;br /&gt;
        appendStringInfoChar(&amp;amp;buf, &#039;\&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
        result = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(buf.data)));&lt;br /&gt;
&lt;br /&gt;
        PG_RETURN_TEXT_P(result);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Za povšimnutí stojí vícenásobná registrace funkce. Jednou pro libovolný typ, jednou pro typ text. To samotnou funkci nijak neovlivní. Všechny systémové parametry jsou stejné a to ať je funkce volaná s typem ANYELEMENT nebo s typem TEXT. quote_literal(text) umožní najít tuto funkci pro typově neurčený řetězec (což je nejčastější případ). Pokud by tato verze funkce chyběla, systém zahlásí chybu ve smyslu, že nemůže použít neznámý typ. Toto omezení postrádá smyslu u C funkcí, neboť neurčený typ je Cstring, který v C je nejen že bezproblémový, ale hlavně jedním se základních typů. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE FUNCTION quote_literal(anyelement)&lt;br /&gt;
RETURNS text&lt;br /&gt;
AS &#039;MODULE_PATHNAME&#039;&lt;br /&gt;
LANGUAGE C STRICT;&lt;br /&gt;
&lt;br /&gt;
CREATE OR REPLACE FUNCTION quote_literal(text)&lt;br /&gt;
RETURNS text&lt;br /&gt;
AS &#039;MODULE_PATHNAME&#039;&lt;br /&gt;
LANGUAGE C STRICT;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tato funkce byla navržena tak, aby emulovala původní chování funkce quote_literal ve verzi 8.3. V této verzi se obecně omezilo automatické přetypování na text. Existuje ale podstatně jednodušší řešení postavené na pg_proc funkci (v jazyce SQL).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE FUNCTION quote_literal(anyelement)&lt;br /&gt;
RETURNS text AS&lt;br /&gt;
$$ SELECT quote_literal($1::text) $$&lt;br /&gt;
LANGUAGE SQL STRICT;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Zhruba 20-30% časové úspory při zobrazování velkých tabulek obsahujících tuto funkci dosáhneme použitím cache. Pro každý sloupec v rámci SQL příkazu má každá funkce vyhrazenou unikátní cache. V tomto případě bude sloužit jako úložiště Oid výstupní funkce (každý typ má přiřazenou tzv. výstupní funkci, která převádí binární hodnotu na hodnotu typ Cstring). Díky tomu odpadne opakované volání funkce getTypeOutputInfo (resp. tato funkce se volá pouze jednou během zpracování SQL příkazu).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Datum&lt;br /&gt;
quote(PG_FUNCTION_ARGS)&lt;br /&gt;
{&lt;br /&gt;
        text *result;&lt;br /&gt;
        Oid         valtype = get_fn_expr_argtype(fcinfo-&amp;gt;flinfo, 0);&lt;br /&gt;
        Datum       value = PG_GETARG_DATUM(0);&lt;br /&gt;
        StringInfoData buf;&lt;br /&gt;
        Oid             *ptr;&lt;br /&gt;
&lt;br /&gt;
        if (!OidIsValid(valtype))&lt;br /&gt;
                elog(ERROR, &amp;quot;could not determine data type of input&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        ptr = (Oid *) fcinfo-&amp;gt;flinfo-&amp;gt;fn_extra;&lt;br /&gt;
        if (ptr == NULL)&lt;br /&gt;
        {&lt;br /&gt;
                Oid                     typoutput;&lt;br /&gt;
                bool            typIsVarlena;&lt;br /&gt;
&lt;br /&gt;
                /* First time calling for current query: allocate storage */&lt;br /&gt;
                fcinfo-&amp;gt;flinfo-&amp;gt;fn_extra = MemoryContextAlloc(fcinfo-&amp;gt;flinfo-&amp;gt;fn_mcxt,&lt;br /&gt;
                                                                                    sizeof(Oid));&lt;br /&gt;
                ptr = (Oid *) fcinfo-&amp;gt;flinfo-&amp;gt;fn_extra;&lt;br /&gt;
&lt;br /&gt;
                getTypeOutputInfo(valtype, &amp;amp;typoutput, &amp;amp;typIsVarlena);&lt;br /&gt;
                *ptr = typoutput;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        initStringInfo(&amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        appendStringInfoChar(&amp;amp;buf, &#039;\&#039;&#039;);&lt;br /&gt;
        appendStringInfoString(&amp;amp;buf, OidOutputFunctionCall(*ptr, value));&lt;br /&gt;
        appendStringInfoChar(&amp;amp;buf, &#039;\&#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
        result = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(buf.data)));&lt;br /&gt;
&lt;br /&gt;
        PG_RETURN_TEXT_P(result);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=Funkce_rownum()&amp;diff=370</id>
		<title>Funkce rownum()</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=Funkce_rownum()&amp;diff=370"/>
		<updated>2007-11-14T16:07:57Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Číslování řádků je takový docela typický problém, který v PostgreSQL není uspokojivě vyřešený. Můžeme použít dočasné sekvence. Ty však musíme vytvářet a resetovat. Tomův návrh tímto neduhem netrpí. Je založený na tom, že každá funkce má pro každý výraz přiřazenou cache omezenou na dobu provádění dotazu. Obyčejně tato cache slouží pro uložení prováděcích plánů, oid funkcí, atd. Nicméně, jelikož toto řešení má daleko do ideálu, není funkce rownum() standardně k dispozici. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
regression=# create function rownum() returns int as &#039;/home/tgl/pgsql/rownum&#039;&lt;br /&gt;
regression-# language c;&lt;br /&gt;
CREATE FUNCTION&lt;br /&gt;
&lt;br /&gt;
regression=# select rownum(),* from int8_tbl;&lt;br /&gt;
 rownum |        q1        |        q2&lt;br /&gt;
--------+------------------+-------------------&lt;br /&gt;
      1 |              123 |               456&lt;br /&gt;
      2 |              123 |  4567890123456789&lt;br /&gt;
      3 | 4567890123456789 |               123&lt;br /&gt;
      4 | 4567890123456789 |  4567890123456789&lt;br /&gt;
      5 | 4567890123456789 | -4567890123456789&lt;br /&gt;
(5 rows)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Řazení probíhá až po vyhodnocení položek v SELECTu. Pokud se tato funkce objeví v SELECTu spolu s klauzulí ORDER BY, dopadne to špatně. Zapouzdřením SUBSELECTu do derivované tabulky už se funkce rownum bude vyhodnocovat až po vyhodnocení ORDER BY, a dostaneme očekávaný výsledek.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
regression=# select rownum(),* from int8_tbl order by q2;&lt;br /&gt;
 rownum |        q1        |        q2&lt;br /&gt;
--------+------------------+-------------------&lt;br /&gt;
      5 | 4567890123456789 | -4567890123456789&lt;br /&gt;
      3 | 4567890123456789 |               123&lt;br /&gt;
      1 |              123 |               456&lt;br /&gt;
      2 |              123 |  4567890123456789&lt;br /&gt;
      4 | 4567890123456789 |  4567890123456789&lt;br /&gt;
(5 rows)&lt;br /&gt;
&lt;br /&gt;
regression=# select rownum(),* from (select * from int8_tbl order by q2) ss;&lt;br /&gt;
 rownum |        q1        |        q2&lt;br /&gt;
--------+------------------+-------------------&lt;br /&gt;
      1 | 4567890123456789 | -4567890123456789&lt;br /&gt;
      2 | 4567890123456789 |               123&lt;br /&gt;
      3 |              123 |               456&lt;br /&gt;
      4 |              123 |  4567890123456789&lt;br /&gt;
      5 | 4567890123456789 |  4567890123456789&lt;br /&gt;
(5 rows)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Vlastní kód funkce:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;postgres.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;fmgr.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef PG_MODULE_MAGIC&lt;br /&gt;
PG_MODULE_MAGIC;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
Datum rownum(PG_FUNCTION_ARGS);&lt;br /&gt;
&lt;br /&gt;
PG_FUNCTION_INFO_V1(rownum);&lt;br /&gt;
&lt;br /&gt;
Datum&lt;br /&gt;
rownum(PG_FUNCTION_ARGS)&lt;br /&gt;
{&lt;br /&gt;
       int32      *ptr;&lt;br /&gt;
&lt;br /&gt;
       ptr = (int32 *) fcinfo-&amp;gt;flinfo-&amp;gt;fn_extra;&lt;br /&gt;
       if (ptr == NULL)&lt;br /&gt;
       {&lt;br /&gt;
               /* First time through for the current query: allocate storage */&lt;br /&gt;
               fcinfo-&amp;gt;flinfo-&amp;gt;fn_extra = MemoryContextAlloc(fcinfo-&amp;gt;flinfo-&amp;gt;fn_mcxt,&lt;br /&gt;
                                                                                   sizeof(int32));&lt;br /&gt;
               ptr = (int32 *) fcinfo-&amp;gt;flinfo-&amp;gt;fn_extra;&lt;br /&gt;
               /* ... and initialize counter */&lt;br /&gt;
               *ptr = 1;&lt;br /&gt;
       }&lt;br /&gt;
       else&lt;br /&gt;
               (*ptr)++;&lt;br /&gt;
&lt;br /&gt;
   PG_RETURN_INT32(*ptr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=Generov%C3%A1n%C3%AD_FAQ_z_wiki_(Python)&amp;diff=365</id>
		<title>Generování FAQ z wiki (Python)</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=Generov%C3%A1n%C3%AD_FAQ_z_wiki_(Python)&amp;diff=365"/>
		<updated>2007-11-01T09:40:30Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pavouk v Pythonu, který z FAQ na wiki vygeneruje FAQ v html v Bruceově formátu:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## coding: UTF-8&lt;br /&gt;
import urllib2&lt;br /&gt;
import sgmllib&lt;br /&gt;
from sets import Set&lt;br /&gt;
import re&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Parser položky FAQ. Musí odfiltrovat wiki balast .. inside_c,&lt;br /&gt;
# přeskočit případně vloženou tabulku s obsahem .. skip_toc&lt;br /&gt;
class ParserItem(sgmllib.SGMLParser):&lt;br /&gt;
    def reset(self):&lt;br /&gt;
        sgmllib.SGMLParser.reset(self)&lt;br /&gt;
        self.flags = Set([])&lt;br /&gt;
&lt;br /&gt;
    def start_div(self,attrs):&lt;br /&gt;
        id = [v for k, v in attrs if k == &#039;id&#039;]&lt;br /&gt;
        classv = [v for k, v in attrs if k == &#039;class&#039;]&lt;br /&gt;
        if id and id[0] == &amp;quot;contentSub&amp;quot;:&lt;br /&gt;
            self.flags.add(&#039;content&#039;)&lt;br /&gt;
        if classv and classv[0] == &amp;quot;printfooter&amp;quot;:&lt;br /&gt;
            self.flags.discard(&#039;content&#039;)&lt;br /&gt;
&lt;br /&gt;
    def end_div(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def end_td(self):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            self.fags.discard(&#039;td&#039;)&lt;br /&gt;
            sys.stdout.write(&amp;quot;&amp;lt;/td&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def start_h3(self, data):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            self.flags.add(&#039;h3&#039;)&lt;br /&gt;
            sys.stdout.write(&amp;quot;&amp;lt;h4&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def end_h3(self):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            self.flags.discard(&#039;h3&#039;)&lt;br /&gt;
            sys.stdout.write(&amp;quot;&amp;lt;/h4&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def start_table(self, attrs):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            id = [v for k, v in attrs if k == &#039;id&#039;]&lt;br /&gt;
            if id and id[0] == &amp;quot;toc&amp;quot;:&lt;br /&gt;
                self.flags.add(&#039;skip_toc&#039;)&lt;br /&gt;
                self.flags.discard(&#039;content&#039;)&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;&amp;lt;table border=\&amp;quot;0\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
            &lt;br /&gt;
    def end_table(self):&lt;br /&gt;
        if &#039;skip_toc&#039; in self.flags:&lt;br /&gt;
            self.flags.discard(&#039;skip_toc&#039;)&lt;br /&gt;
            self.flags.add(&#039;content&#039;)&lt;br /&gt;
        else:&lt;br /&gt;
            if &#039;content&#039; in self.flags:&lt;br /&gt;
                print &amp;quot;&amp;lt;/table&amp;gt;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # Párové tagy &amp;lt;pre&amp;gt; a &amp;lt;p&amp;gt; nesou zajímavý obsah &lt;br /&gt;
    def unknown_starttag(self, tag, attrs):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            sys.stdout.write(&amp;quot;&amp;lt;%s&amp;gt;&amp;quot; % tag)&lt;br /&gt;
            if tag in [&#039;pre&#039;,&#039;p&#039;,&#039;li&#039;,&#039;td&#039;]:&lt;br /&gt;
                self.flags.add(tag)&lt;br /&gt;
&lt;br /&gt;
    def unknown_endtag(self, tag):         &lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            print &amp;quot;&amp;lt;/%s&amp;gt;&amp;quot; % tag&lt;br /&gt;
            if tag in [&#039;pre&#039;,&#039;p&#039;,&#039;li&#039;,&#039;td&#039;]:&lt;br /&gt;
                self.flags.discard(tag)&lt;br /&gt;
&lt;br /&gt;
    def handle_data(self, data):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            if len(Set([&#039;pre&#039;,&#039;p&#039;,&#039;li&#039;,&#039;td&#039;]) &amp;amp; self.flags) &amp;gt; 0:&lt;br /&gt;
                sys.stdout.write(data)&lt;br /&gt;
&lt;br /&gt;
    def start_a(self, attrs):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            href = [v for k, v in attrs if k == &#039;href&#039;]&lt;br /&gt;
            title = [v for k, v in attrs if k == &#039;title&#039;]&lt;br /&gt;
            if title and re.match(&#039;^Edit&#039;, title[0]):&lt;br /&gt;
                self.flags.add(&#039;skip_close_a&#039;)&lt;br /&gt;
            else:&lt;br /&gt;
                if title and href:&lt;br /&gt;
                    self.flags.add(&#039;a&#039;)&lt;br /&gt;
                    sys.stdout.write(&amp;quot;&amp;lt;a href=\&amp;quot;%s\&amp;quot; title=\&amp;quot;%s\&amp;quot;&amp;gt;&amp;quot; % (href[0], title[0]))&lt;br /&gt;
&lt;br /&gt;
    def end_a(self):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            self.flags.discard(&#039;a&#039;)&lt;br /&gt;
            if &#039;skip_close_a&#039; in self.flags: &lt;br /&gt;
                self.flags.discard(&#039;skip_close_a&#039;)&lt;br /&gt;
            else:&lt;br /&gt;
                sys.stdout.write(&amp;quot;&amp;lt;/a&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Parser hlavní stránky. V podstatě jenom filtruje odkazy&lt;br /&gt;
# začínající číslicí a skrz regulární výrazy z nich dělá nadpisy.&lt;br /&gt;
# Pro každý identifikovaný odkaz spustí načtení detailu FAQ&lt;br /&gt;
class ParserMainPage(sgmllib.SGMLParser):&lt;br /&gt;
    def reset(self):&lt;br /&gt;
        sgmllib.SGMLParser.reset(self)&lt;br /&gt;
        self.inside_h1 = 0&lt;br /&gt;
&lt;br /&gt;
    def start_h1(self, data):&lt;br /&gt;
        self.inside_h1 = 1&lt;br /&gt;
&lt;br /&gt;
    def end_h1(self):&lt;br /&gt;
        self.inside_h1 = 0&lt;br /&gt;
&lt;br /&gt;
    def handle_data(self, data):&lt;br /&gt;
        if self.inside_h1:&lt;br /&gt;
            if re.match(&#039;^\d&#039;, data):&lt;br /&gt;
                print &amp;quot;&amp;lt;hr&amp;gt;&amp;quot;&lt;br /&gt;
                print &amp;quot;&amp;lt;h2 align=\&amp;quot;center\&amp;quot;&amp;gt;%s&amp;lt;/h2&amp;gt;&amp;quot; % re.sub(&#039;\d\. &#039;,&#039;&#039;,data)&lt;br /&gt;
&lt;br /&gt;
    def start_a(self, attrs):&lt;br /&gt;
        href = [v for k, v in attrs if k == &#039;href&#039;]&lt;br /&gt;
        title = [v for k, v in  attrs if k == &#039;title&#039;]&lt;br /&gt;
        if title and re.match(&#039;^\d\.&#039;,title[0]):&lt;br /&gt;
            if re.match(&#039;(\d)\.0?(\d{1,2})+(\.\d)&#039;, title[0]):&lt;br /&gt;
                print &amp;quot;&amp;lt;h3&amp;gt;%s&amp;lt;/h3&amp;gt;&amp;quot; % re.sub(&#039;(\d)\.0?(\d{1,2})+(\.\d)&#039;,&#039;&amp;lt;a name=&amp;quot;item\\1.\\2\\3&amp;quot;&amp;gt;\\1.\\2\\3&amp;lt;/a&amp;gt;)&#039;, title[0])&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;&amp;lt;h3&amp;gt;%s&amp;lt;/h3&amp;gt;&amp;quot; % re.sub(&#039;(\d)\.0?(\d{1,2})+&#039;,&#039;&amp;lt;a name=&amp;quot;item\\1.\\2&amp;quot;&amp;gt;\\1.\\2&amp;lt;/a&amp;gt;)&#039;, title[0])&lt;br /&gt;
            iresp = urllib2.urlopen(&amp;quot;http://www.pgsql.cz&amp;quot; + href[0])&lt;br /&gt;
            item = iresp.read()&lt;br /&gt;
            iresp.close()&lt;br /&gt;
            parserItem = ParserItem()&lt;br /&gt;
            parserItem.feed(item)&lt;br /&gt;
            parserItem.close()&lt;br /&gt;
&lt;br /&gt;
# Parsuje odstavce v FAQ (metainformace) a seznam otázek&lt;br /&gt;
# uvedený na začátku FAQ&lt;br /&gt;
class ParserMainPageProlog(sgmllib.SGMLParser):&lt;br /&gt;
    def reset(self):&lt;br /&gt;
        sgmllib.SGMLParser.reset(self)&lt;br /&gt;
        self.flags = Set([])&lt;br /&gt;
&lt;br /&gt;
    def start_div(self,attrs):&lt;br /&gt;
        id = [v for k, v in attrs if k == &#039;id&#039;]&lt;br /&gt;
        classv = [v for k, v in attrs if k == &#039;class&#039;]&lt;br /&gt;
        if id and id[0] == &amp;quot;contentSub&amp;quot;:&lt;br /&gt;
            self.flags.add(&#039;content&#039;)&lt;br /&gt;
        if classv and classv[0] == &amp;quot;printfooter&amp;quot;:&lt;br /&gt;
            self.flags.discard(&#039;content&#039;)&lt;br /&gt;
&lt;br /&gt;
    def end_div(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def unknown_starttag(self, tag, attrs):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            sys.stdout.write(&amp;quot;&amp;lt;%s&amp;gt;&amp;quot; % tag)&lt;br /&gt;
            if tag in [&#039;p&#039;]:&lt;br /&gt;
                self.flags.add(tag)&lt;br /&gt;
&lt;br /&gt;
    def unknown_endtag(self, tag):         &lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            sys.stdout.write(&amp;quot;&amp;lt;/%s&amp;gt;&amp;quot; % tag)&lt;br /&gt;
            if tag in [&#039;p&#039;]:&lt;br /&gt;
                self.flags.discard(tag)&lt;br /&gt;
&lt;br /&gt;
    def start_h1(self, data):&lt;br /&gt;
        self.flags.add(&#039;h1&#039;)&lt;br /&gt;
&lt;br /&gt;
    def end_h1(self):&lt;br /&gt;
        self.flags.discard(&#039;h1&#039;)&lt;br /&gt;
&lt;br /&gt;
    def handle_data(self, data):&lt;br /&gt;
        if &#039;h1&#039; in self.flags:&lt;br /&gt;
            if re.match(&#039;^\d&#039;, data):&lt;br /&gt;
                if re.match(&#039;1&#039;, data):&lt;br /&gt;
                    print &amp;quot;&amp;lt;hr&amp;gt;&amp;quot;&lt;br /&gt;
                print &amp;quot;&amp;lt;h2 align=\&amp;quot;center\&amp;quot;&amp;gt;%s&amp;lt;/h2&amp;gt;&amp;quot; % re.sub(&#039;\d\. &#039;,&#039;&#039;,data)&lt;br /&gt;
        else:&lt;br /&gt;
            if &#039;p&#039; in self.flags:&lt;br /&gt;
                sys.stdout.write(data)&lt;br /&gt;
&lt;br /&gt;
    def start_a(self, attrs):&lt;br /&gt;
        href = [v for k, v in attrs if k == &#039;href&#039;]&lt;br /&gt;
        title = [v for k, v in  attrs if k == &#039;title&#039;]&lt;br /&gt;
        if title and re.match(&#039;^\d\.&#039;,title[0]):&lt;br /&gt;
            if re.match(&#039;(\d)\.0?(\d{1,2})+(\.\d)&#039;, title[0]):&lt;br /&gt;
                print &amp;quot;%s&amp;lt;br&amp;gt;&amp;quot; % re.sub(&#039;(\d)\.0?(\d{1,2})+(\.\d)&#039;,&#039;&amp;lt;a href=&amp;quot;#item\\1.\\2\\3&amp;quot;&amp;gt;\\1.\\2\\3&amp;lt;/a&amp;gt;)&#039;, title[0])&lt;br /&gt;
            else:&lt;br /&gt;
                print &amp;quot;%s&amp;lt;br&amp;gt;&amp;quot; % re.sub(&#039;(\d)\.0?(\d{1,2})+&#039;,&#039;&amp;lt;a href=&amp;quot;#item\\1.\\2&amp;quot;&amp;gt;\\1.\\2&amp;lt;/a&amp;gt;)&#039;, title[0])&lt;br /&gt;
            self.flags.add(&#039;skip_close_a&#039;)&lt;br /&gt;
        elif title and re.match(&#039;^Edit&#039;, title[0]):&lt;br /&gt;
            self.flags.add(&#039;skip_close_a&#039;)&lt;br /&gt;
        else:&lt;br /&gt;
            if title and href and &#039;content&#039; in self.flags:&lt;br /&gt;
                self.flags.add(&#039;a&#039;)&lt;br /&gt;
                sys.stdout.write(&amp;quot;&amp;lt;a href=\&amp;quot;%s\&amp;quot; title=\&amp;quot;%s\&amp;quot;&amp;gt;&amp;quot; % (href[0], title[0]))&lt;br /&gt;
&lt;br /&gt;
    def end_a(self):&lt;br /&gt;
        if &#039;content&#039; in self.flags:&lt;br /&gt;
            self.flags.discard(&#039;a&#039;)&lt;br /&gt;
            if &#039;skip_close_a&#039; not in self.flags:&lt;br /&gt;
                sys.stdout.write(&amp;quot;&amp;lt;/a&amp;gt;&amp;quot;)&lt;br /&gt;
            else:&lt;br /&gt;
                self.flags.discard(&#039;skip_close_a&#039;)&lt;br /&gt;
&lt;br /&gt;
    def start_ul(self, data):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def start_li(self, data):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def end_ul(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def end_li(self):&lt;br /&gt;
        pass &lt;br /&gt;
&lt;br /&gt;
    def end_div(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
response = urllib2.urlopen(&amp;quot;http://www.pgsql.cz/index.php/Frequently_Asked_Questions&amp;quot;)&lt;br /&gt;
html = response.read()&lt;br /&gt;
response.close()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;&amp;lt;!DOCTYPE HTML PUBLIC \&amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;html&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;head&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;title&amp;gt;PostgreSQL FAQ&amp;lt;/title&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;meta http-equiv=\&amp;quot;Content-Type\&amp;quot; content=\&amp;quot;text/html; charset=utf-8\&amp;quot; /&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;meta http-equiv=\&amp;quot;Content-language\&amp;quot; content=\&amp;quot;cs\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;meta name=\&amp;quot;description\&amp;quot; lang=\&amp;quot;en\&amp;quot; content=\&amp;quot;Czech translation of FAQ for PostgreSQL\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;meta name=\&amp;quot;description\&amp;quot; lang=\&amp;quot;cs\&amp;quot; content=\&amp;quot;Český překlad FAQ PostgreSQL\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;body bgcolor=\&amp;quot;#ffffff\&amp;quot; text=\&amp;quot;#000000\&amp;quot; link=\&amp;quot;#ff0000\&amp;quot; vlink=\&amp;quot;#a00000\&amp;quot; alink=\&amp;quot;#0000ff\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;h1&amp;gt;Frequently Asked Questions&amp;lt;/h1&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
parser2 = ParserMainPageProlog()&lt;br /&gt;
parser2.short_run = 0&lt;br /&gt;
parser2.feed(html)&lt;br /&gt;
parser2.close()&lt;br /&gt;
&lt;br /&gt;
parser = ParserMainPage()&lt;br /&gt;
parser.feed(html)&lt;br /&gt;
parser.close()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;&lt;br /&gt;
print &amp;quot;&amp;lt;/htm&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=1.03_Pod_jakou_licenc%C3%AD_je_PostgreSQL%3F&amp;diff=122</id>
		<title>1.03 Pod jakou licencí je PostgreSQL?</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=1.03_Pod_jakou_licenc%C3%AD_je_PostgreSQL%3F&amp;diff=122"/>
		<updated>2007-10-31T15:13:03Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PostgreSQL je předmětem následujících autorských práv:&lt;br /&gt;
   &lt;br /&gt;
Dílčí Copyright (c) 1996-2005, PostgreSQL Global Development Group&amp;lt;br&amp;gt;&lt;br /&gt;
Dílčí Copyright (c) 1994-6, Regents of the University of California&lt;br /&gt;
   &lt;br /&gt;
Uděluje se oprávnění k užití, rozmnožování, provádění úprav a&lt;br /&gt;
rozšiřování tohoto softwaru a dokumentace k němu, pro jakékoli účely,&lt;br /&gt;
bez licenčního poplatku a bez písemné licenční smlouvy, za podmínky,&lt;br /&gt;
že na všech jeho kopiích je uvedeno oznámení o výše uvedených právech,&lt;br /&gt;
jakož i obsah tohoto a dvou následujících odstavců.&lt;br /&gt;
   &lt;br /&gt;
THE UNIVERSITY OF CALIFORNIA (&amp;quot;KALIFORNSKÁ UNIVERZITA&amp;quot;) NENÍ V ŽÁDNÉM&lt;br /&gt;
PŘÍPADĚ ODPOVĚDNA ŽÁDNÉ TŘETÍ OSOBĚ ZA PŘÍMOU, NEPŘÍMOU, ZVLÁŠTNÍ,&lt;br /&gt;
NAHODILOU NEBO VÝSLEDNOU ŠKODU, VČETNĚ UŠLÉHO ZISKU, ZPŮSOBENOU UŽITÍM&lt;br /&gt;
TOHOTO SOFTWARU A DOKUMENTACE K NĚMU, A TO I V PŘÍPADĚ, ŽE THE&lt;br /&gt;
UNIVERSITY OF CALIFORNIA BYLA INFORMOVÁNA O MOŽNOSTI VZNIKU TAKOVÉ&lt;br /&gt;
ŠKODY.&lt;br /&gt;
   &lt;br /&gt;
THE UNIVERSITY OF CALIFORNIA ZEJMÉNA NEPOSKYTUJE JAKÉKOLI ZÁRUKY, A TO&lt;br /&gt;
NEJEN ZÁRUKY OBCHODOVATELNOSTI A VHODNOSTI TOHOTO VÝROBKU KE&lt;br /&gt;
SPECIFICKÝM ÚČELŮM. NÍŽE UVEDENÝ SOFTWARE JE POSKYTNUT &amp;quot;JAK STOJÍ A&lt;br /&gt;
LEŽÍ&amp;quot; A THE UNIVERSITY OF CALIFORNIA NENÍ POVINNA ZAJISTIT JEHO&lt;br /&gt;
ÚDRŽBU, PODPORU, AKTUALIZACI, VYLEPŠENÍ NEBO MODIFIKACI.&lt;br /&gt;
   &lt;br /&gt;
Výše uvedené je BSD licence, běžná licence otevřeného zdroje. Není zde&lt;br /&gt;
žádné omezení ohledně užití kódu zdroje. Jsme s tím spokojeni a nemáme&lt;br /&gt;
v úmyslu na této skutečnosti cokoli měnit.&lt;br /&gt;
[[Category:1. Obecné otázky]]&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=4.11.3_Nezp%C5%AFsob%C3%AD_currval()_a_nextval()_probl%C3%A9my_ve_v%C3%ADce_u%C5%BEivatelsk%C3%A9m_prost%C5%99ed%C3%AD%3F&amp;diff=174</id>
		<title>4.11.3 Nezpůsobí currval() a nextval() problémy ve více uživatelském prostředí?</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=4.11.3_Nezp%C5%AFsob%C3%AD_currval()_a_nextval()_probl%C3%A9my_ve_v%C3%ADce_u%C5%BEivatelsk%C3%A9m_prost%C5%99ed%C3%AD%3F&amp;diff=174"/>
		<updated>2007-10-31T15:11:18Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ne, currval vrací vždy hodnotu, která byla vygenerována pro vás.&lt;br /&gt;
[[Category:4. Provozní dotazy]]&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=3.05_Co_znamen%C3%A1_%22Sorry,_too_many_clients%22,_kdy%C5%BE_se_zkou%C5%A1%C3%ADm_p%C5%99ipojit%3F&amp;diff=157</id>
		<title>3.05 Co znamená &quot;Sorry, too many clients&quot;, když se zkouším připojit?</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=3.05_Co_znamen%C3%A1_%22Sorry,_too_many_clients%22,_kdy%C5%BE_se_zkou%C5%A1%C3%ADm_p%C5%99ipojit%3F&amp;diff=157"/>
		<updated>2007-10-31T14:57:56Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Překročil jste výchozí limit, který je 100 současně připojených uživatelů. V konfiguraci serveru v postgresql.conf tuto hodnotu můžete zvětšit změnou hodnoty max_connection. Nezapomeňte restartovat server.&lt;br /&gt;
[[Category:3. Administrativní dotazy]]&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=1.02_Kdo_%C5%99%C3%ADd%C3%AD_v%C3%BDvoj_PostgreSQL%3F&amp;diff=121</id>
		<title>1.02 Kdo řídí vývoj PostgreSQL?</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=1.02_Kdo_%C5%99%C3%ADd%C3%AD_v%C3%BDvoj_PostgreSQL%3F&amp;diff=121"/>
		<updated>2007-10-31T14:54:47Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Pokud budete hledat organizaci řídící vývoj PostgreSQL, budete zklamáni. Nic takového&lt;br /&gt;
neexistuje. Existují pouze &amp;quot;core&amp;quot; a CVS skupiny uživatelů, ale ty existují více z administrátorských&lt;br /&gt;
důvodů než z organizačních. Projekt je směrován komunitou vývojářů a uživatelů, ke které se &lt;br /&gt;
kdokoliv může připojit. Jediné co potřebuje, je přihlásit se do elektronické konference. Více ve &lt;br /&gt;
[http://www.postgresql.org/docs/faqs.FAQ_DEV.html vývojářském FAQ].&lt;br /&gt;
&lt;br /&gt;
[[Category:1. Obecné otázky]]&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
	<entry>
		<id>http://postgres.cz/index.php?title=602SQL_Server&amp;diff=307</id>
		<title>602SQL Server</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=602SQL_Server&amp;diff=307"/>
		<updated>2007-10-04T07:05:40Z</updated>

		<summary type="html">&lt;p&gt;130.225.61.3: /* S křížem po funuse (aneb otevření kódu 602SQL Serveru pod LGPL) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==S křížem po funuse (aneb otevření kódu 602SQL Serveru pod LGPL)==&lt;br /&gt;
Překvapivé [http://www.602.cz/cz/o_firme/tiskove_zpravy/602sql_open_server_je_nyni_volne_k_dispozici_pro_komercni_i_nekomercni_pouziti prohlášení] 602Software o [http://sourceforge.net/project/showfiles.php?group_id=203848 otevření kódu] [http://www.602.cz/cz/produkty/602sql_open_server_11_0 602SQL Serveru] je patrně jedou ze zásadních událostí na domácí IT scéně. Je to důležitý precedens. 602SQL Server je ukázkou, jak relativně kvalitní produkt díky špatnému marketingu a nedostatečné podpoře nedokáže držet krok s konkurenčními produkty a posléze ani s open source konkurencí. Otevření kódu v případě 602SQL Serveru bohužel přichází pozdě, kdy je jen malá šance na jeho revitalizaci.&lt;br /&gt;
&lt;br /&gt;
==S křížem po funuse (aneb otevření kódu 602SQL Serveru pod LGPL)==&lt;br /&gt;
Se jménem RNDr. Januše Drózda jsem se poprvé setkal ještě v osmdesátých letech, kdy ještě spolu s Petrem Coufem napsali překladač a prostředí tzv. Mikrobáze Pascalu pro ZxSpectrum. Bylo to v roce 1986 a byla to absolutní bomba. Prostředí MB Pascalu bylo na poměry ZxSpectra nadupané funkcemi. Škoda, že už nepřepsali MB Pascal pro Didaktik Gama, který přeci jen měl o 32K paměti víc. S tím už by se daly dělat věci. Nebudu asi jediný, kdo díky jejich práci, zůstal u počítačů a živí se v it. Pak už přišlo CP/M s TurboPascalem 3.0, poté první PC a přelomové verze Turbo Pascalu 5.0 a 6.0. Zřejmě to nebyla náhoda, že první produkty 602 měly integrovaný Pascal. První funkce v S-Pascalu jsem napsal v Calc602, což byl na svou dobu docela progresivní spreadsheet. V devadesátých letech začal 602 ujíždět vlak. Calc602 byl první tabulkový procesor s integrovaným plnohodnotným jazykem, ale byl a zůstal pouze ve verzi pro DOS a byl neskutečně pomalý. Co se dělo v té době v 602 nevím, pro mne naprosto nepochopitelně 602 postupně vyklízela veškeré pozice. Produkty, které byly uvedeny na trh, byly uvedeny pozdě a za naprosto nesmyslné ceny (v cenových relacích ne nepodobných Microsoftu). V 602 si až příliš pozdě všimli, že existují Microsoft Windows, a později, opět, podcenili konkurenci Open Source. Na RNDr. Januše Drózda nevzpomínám z návalu nostalgie, ale proto, že je jedním z autorů 602SQL Serveru - SQL RNDBS, jehož kód byl minulý týden otevřen pod licencí LGPL.&lt;br /&gt;
&lt;br /&gt;
Podle optimistického vyjádření obchodního řiditele 602 je otevření 602SQL Serveru pod LGPL dlouho připravovaným krokem, který má zajistit produktu další vývoj. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;„Uvolnit software do open source není tak jednoduché, jak by se mohlo na první pohled zdát. Zdrojový kód je naší vizitkou a jakákoliv nešikovnost nebo dokonce chyba by byla okamžitě veřejně viditelná. A samozřejmě, že jsme zvažovali i obchodní stránku věci. Ale jsme přesvědčeni, že to bylo rozhodnutí potřebné a správné. Globální komunita open source je obohacena o dobrý databázový produkt, prestiž českých vývojářů dále vzrostla a práce tisíců IT expertů celého světa zajistí produktu další rozvoj. To je kombinace, na níž nakonec vydělají všichni zúčastnění,“&amp;lt;/i&amp;gt; řekl obchodní ředitel Software602 Ing. Pavel Nemrava.&lt;br /&gt;
&lt;br /&gt;
[[Image:602SQL.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
Nejsem tak optimistický. Nevím, ale obávám se, že Ing. Nemrava zažije nepříjemné zklamání. IT expertů, kteří se účastní vývoje open source databází, rozhodně nejsou tisíce. Vývojářů Firebirdu je něco kolem desítky, PostgreSQL je výsledkem práce zhruba max. třech desítek lidí z celého světa a řekl bych, že podobně na tom budou u MySQL. Kdyby k otevření kódu došlo před čtyřmi roky, tak by možná 602SQL Server mohl přetáhnout vývojáře Firebirdu nebo PostgreSQL a zaujmout snad lepší  postavení. Nemyslím si, že by kdokoliv dnes investoval do vývoje dalšího databázového serveru. Ještě před čtyřmi lety byla jiná situace. Stejně tak pozdě přišlo otevření SAPDB a Ingressu. A je mi to, přiznám se, docela líto. Na to jaké má 602SQL Server nároky, toho umí fakt hodně. Implementace SQL respektuje standard, je konzistentní a úplná. GUI je praktické a funkční. Není mi známo, kolik vývojářů stojí za 602SQL Serverem, odhadoval bych to tak na 1-3, což opět nedává 602SQL příliš šancí. Poslední tři verze byly víc zaměřené na klientské rozhraní a na opravu chyb než na databázový engine. Každý si musí udělat jednoznačný obrázek při porovnání Release Notes 602SQL a PostgreSQL, Firebirdu nebo MySQL. Ono se toho ale v málo lidech příliš udělat nedá.&lt;br /&gt;
&lt;br /&gt;
Jako největší mínus vidím dlouhodobě špatnou podporu z 602. Oficiální fórum má poslední odpověď Jana Šímy z června 2002. Neoficiální fórum uživatelů na pandoře.cz stále žije, nicméně podle počtu příspěvků je zřejmé, že zenit 602SQL Serveru byl v roce 2003. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1999 (3)] [2000 (0)] [2001 (0)] [2002 (189)] [2003 (306)] [2004 (107)] [2005 (58)] [2006 (19)] [2007 (32)] &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Druhé a zásadní mínus, pro open source vývoj, je nedostatek (resp. neexistence) vývojářské dokumentace. Nikde jsem nenašel popis zpracování dotazu, popis architektury, datového formátu, atd. Buďto neexistuje, a nebo tuto dokumentaci 602 nechce zveřejnit. Bez této dokumentace není pravděpodobné, že by se někdo vážněji 602SQL Serverem zabýval. Zdrojový kód je docela hutný a bez znalosti interních mechanismů nedešifrovatelný. Hádám, že minimálně 30% komentářů je v češtině. Tudíž potenciální vývojáři se musí rekrutovat z Čech nebo Slovenska. Kdo zná zdejší komunitu, ví jaký je tu nedostatek vývojářů. &lt;br /&gt;
&lt;br /&gt;
Databázové produkty 602 trpí nekoncepčností. Nejdříve tu byl klasický relační databázový systém 4GL, poté databáze, která se snažila o symbiózu jak 4GL architektury, tak architektury klient/server a nakonec 602SQL Server je ukázkovou aplikací klient/server. To, že 602SQL Server přišel o 4GL vlastnosti hodně uživatelů nepochopilo a odmítlo. To, že 602 se snažila o prosazení vlastního prostředí pro vývoj www aplikací, jsem zase nechápal já. V době PHP nebo ASP neměli šanci, bez ohledu na to, jak kvalitní jejich návrh byl. &lt;br /&gt;
&lt;br /&gt;
Ze zvědavosti jsem si 602SQL Server nainstaloval a dva dny jsem si hrál. Test na vyhledávání prvočísel není typickým databázovým testem, ale generuje velký počet triviálních příkazů SELECT a DELETE. Pokud používáte triviální nebo jednoduché SQL příkazy, pak v reálné aplikaci (v jednouživatelském režimu) nikdy nebude rozdíl mezi databázovými platformami větší než jaký ukazuje tento test (PostgreSQL je jednou tak rychlejší co 602SQL Server, což je). Test pgbench testuje průchodnost serveru ve víceuživatelském prostředí, obsahuje jak dotazy na data, tak změny dat. Netýral jsem 602SQL Server komplikovanými SQL dotazy .. vzhledem k tomu, že jeho query planner není postavený na posouzení nákladů na provedení dotazu, by byl 602SQL Server těžce znevýhodněn vůči PostgreSQL. Obdobný Q.P. měly i starší verze Firebirdu a MySQL. Současné verze mají podobně navržen Q.P. jako PostgreSQL. Jaký typ Q.P. má 602SQL Server skutečně, jsem se nikde nedozvěděl. To, že se jedná o první generaci Q.P. spíš odhaduji z neexistence statistik. &lt;br /&gt;
&lt;br /&gt;
Testovací příklad (určení prvočísel):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FUNCTION siete( ) RETURNS integer; -- zde podle ANSI SQL nemá být středník (snad &lt;br /&gt;
BEGIN                              -- jediný prohřešek standardu)&lt;br /&gt;
  DECLARE _f integer;&lt;br /&gt;
  DECLARE _l integer DEFAULT 1;&lt;br /&gt;
s_loop: &lt;br /&gt;
  LOOP&lt;br /&gt;
    SET _f = (SELECT MIN(a) &lt;br /&gt;
                 FROM numbers&lt;br /&gt;
                WHERE a &amp;gt; _l);&lt;br /&gt;
    IF _f IS NULL THEN LEAVE s_loop; END IF;&lt;br /&gt;
    DELETE &lt;br /&gt;
       FROM numbers&lt;br /&gt;
      WHERE a MOD _f = 0 AND a &amp;gt; _f;&lt;br /&gt;
    SET _l = _f;&lt;br /&gt;
  END LOOP;&lt;br /&gt;
  RETURN (SELECT COUNT(*) &lt;br /&gt;
             FROM numbers);&lt;br /&gt;
END;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
S dalším testem bylo víc práce.  Aplikační rozhraní 602SQL Serveru se dost liší od API PostgreSQL. Ovšem výsledky mají, pro mně, podstatně vyšší váhu než určování prvočísel. Díky pgbench testu si lze ověřit průchodnost databáze při vysokém zatížení v typizovaném podnikovém prostředí. Výsledky ukazují, že 602SQL server drží krok s Postgresem pouze v případě menším počtu transakcí na spojení a při malém počtu klientů (a pokud se nevynucuje zápis změn při commitu). Tady je třeba konstatovat, že pouze vynucený zápis změn při commitu zaručuje konzistenci databáze, a že výchozí nastavení 602SQL Serveru není bezpečné. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1 klient	                1Kt	5Kt	10Kt	&lt;br /&gt;
602SQL Server 	 fsync = off    1.2s	16.5s	1m51.1s	&lt;br /&gt;
		 fsync = on	9.0s		2m20.6s&lt;br /&gt;
&lt;br /&gt;
PostgreSQL 8.3	fsync = on	1.4s		13.6s&lt;br /&gt;
&lt;br /&gt;
klientů (1000 transakcí)	1	3	10&lt;br /&gt;
602SQL Server	fsync = off	1.2s	3.7s	29s&lt;br /&gt;
PostgreSQL 8.3	fsync = on	1.4s	3.7	14s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Samozřejmě, že to není fér vůči 602SQL Serveru (I když verze 11 je v podstatě pouze o půl roku starší než PostgreSQL8.3). Multi generační architektura PostgreSQL je při více uživatelském přístupu zásadní výhodou. &lt;br /&gt;
&lt;br /&gt;
Plusy a mínusy na které jsem narazil:&lt;br /&gt;
&lt;br /&gt;
Plusy:&lt;br /&gt;
* přitažlivé prakticky navržené jednoduché administrativní prostředí,&lt;br /&gt;
* konzistentní a dostatečně široká podpora SQL respektující standard,&lt;br /&gt;
* jednoduchá administrace (v podstatě není co konfigurovat),&lt;br /&gt;
* česky psaná dokumentace (psaná víc pro programátory než pro DBA),&lt;br /&gt;
* fulltext podporuje češtinu (podpora COLLATES je na velice dobré úrovni),&lt;br /&gt;
* IDE dynamicky zobrazuje počet aktualizovaných řádků DML příkazem,&lt;br /&gt;
* cca 3M zdrojových kódů databázového jádra,&lt;br /&gt;
* úplná podpora uložených procedur dle standardu (IN OUT parametry, procedury a funkce, volné dotazy (multirecordset), což je hodně praktická vlastnost, která ovšem není zakotvena ve standardu),&lt;br /&gt;
* Integrovaný profiler a integrovaný debugger uložených procedur,&lt;br /&gt;
* limit pro typ text je 16M.&lt;br /&gt;
&lt;br /&gt;
Mínusy:&lt;br /&gt;
* neodladěná instalace v prostředí Linux (a to nepoužívám žádnou exotickou distribuci),&lt;br /&gt;
* problémy s kompilací (neodladěnost pro vícero platforem),&lt;br /&gt;
* V IDE nelze přerušit prováděný SQL příkaz,&lt;br /&gt;
* limit 4G na tabulku,&lt;br /&gt;
* neexistence jakékoliv popisu interních procesů, datových struktur, atd vyjma komentářů, kromě oficiální uživatelské příručky neexistují žádné další zdroje,&lt;br /&gt;
* při intenzivní zátěži občas nestabilní, nelineární závislost průchodnosti serveru a zátěže, &lt;br /&gt;
* obsahuje komentáře v češtině (mám rád, ale nepatří do o.s. produktu),&lt;br /&gt;
* neexistence (utajení) zodpovědných (klíčových) osob v projektu, kritický nedostatek uživatelů - neexistují žádné věrohodné studie použití 602SQL Serveru v praxi (zvlášť při větším zatížení a větších aplikacích)&lt;br /&gt;
* starší verze Q.P.  (stejná generace byla v Firebirdu 1.x a MySQL 4.x),&lt;br /&gt;
* kromě profileru a tabulky zámků chybí detailnější diagnostika,&lt;br /&gt;
* zdrojový kód obsahuje pravděpodobně mrtvý kód (např. parser S-Pascalu, který oficiálně není podporován, stejně tak replikace). U řady modulů byla poslední revize naposledy v roce 1992, tj. zdrojový kód vyžaduje revizi (kterou po svém vzniku prošel jak Firebird  tak PostgreSQL),&lt;br /&gt;
* placený fulltext.&lt;br /&gt;
&lt;br /&gt;
Specifika:&lt;br /&gt;
* zabudovaný jednoduchý HTTP server umožňující výměnu dat ve formátu XML (placený),&lt;br /&gt;
* starší verze podporovali replikaci skrz elektronickou poštu (602 je mistrem v prošlapávání slepých cest - &amp;quot;českých řešení&amp;quot;) ,&lt;br /&gt;
* spolu s 602SQL Serverem je dodávaný SMTP a POP3 server, který jako úložiště používá SQL server.&lt;br /&gt;
&lt;br /&gt;
Je pro Vás 602SQL Server? a) pokud udržujete produkt, který je na 602SQL Serveru závislý a neplánujete absolutní refaktoring, pak 602SQL Server je to pravé ořechové, b) pokud jste pamětníci a z nostalgie sbíráte artefakty historie IT (doma oprašujete PC Fand), pak (602SQL Server má nepochybně své místo v historii české IT) 602SQL Server musíte mít, c) pokud studujete IT, pak v 602SQL Serveru dostanete balík kódu, který je funkční, a který není tak objemný, jako konkurenční databáze. Docela bych si dovedl představit použití 602SQL Serveru na středních i vysokých školách pro výuku databází (100% jako náhrada MS Accessu). Pokud by si dal někdo práci a pohrál si instalací, pak by možná pár dalších lidí si tento SQL server nainstalovalo a používalo. Určitě 602SQL Server má na to, aby se na něm daly stavět menší aplikace. Ale je tu příliš velké riziko, že jeho vývoj skončí. Otevřený kód alespoň garantuje šanci opravit chyby na které se časem přijde.&lt;/div&gt;</summary>
		<author><name>130.225.61.3</name></author>
	</entry>
</feed>