Added: avro/site/publish/docs/1.11.3/specification/_print/index.html
URL: 
http://svn.apache.org/viewvc/avro/site/publish/docs/1.11.3/specification/_print/index.html?rev=1919887&view=auto
==============================================================================
--- avro/site/publish/docs/1.11.3/specification/_print/index.html (added)
+++ avro/site/publish/docs/1.11.3/specification/_print/index.html Wed Aug 14 
13:30:06 2024
@@ -0,0 +1,236 @@
+<!doctype html><html lang=en class=no-js><head><meta charset=utf-8><meta 
name=viewport 
content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta 
name=generator content="Hugo 0.113.0"><link rel=canonical type=text/html 
href=/docs/1.11.3/specification/><link rel=alternate type=application/rss+xml 
href=/docs/1.11.3/specification/index.xml><meta name=robots content="noindex, 
nofollow"><link rel=apple-touch-icon sizes=57x57 
href=https://apache.org/favicons/apple-touch-icon-57x57.png><link 
rel=apple-touch-icon sizes=60x60 
href=https://apache.org/favicons/apple-touch-icon-60x60.png><link 
rel=apple-touch-icon sizes=72x72 
href=https://apache.org/favicons/apple-touch-icon-72x72.png><link 
rel=apple-touch-icon sizes=76x76 
href=https://apache.org/favicons/apple-touch-icon-76x76.png><link 
rel=apple-touch-icon sizes=114x114 
href=https://apache.org/favicons/apple-touch-icon-114x114.png><link 
rel=apple-touch-icon sizes=120x120 
href=https://apache.org/favicons/apple-touch-icon-120x120.png><
 link rel=apple-touch-icon sizes=144x144 
href=https://apache.org/favicons/apple-touch-icon-144x144.png><link 
rel=apple-touch-icon sizes=152x152 
href=https://apache.org/favicons/apple-touch-icon-152x152.png><link 
rel=apple-touch-icon sizes=180x180 
href=https://apache.org/favicons/apple-touch-icon-180x180.png><link rel=icon 
type=image/png href=https://apache.org/favicons/favicon-32x32.png 
sizes=32x32><link rel=icon type=image/png 
href=https://apache.org/favicons/favicon-194x194.png sizes=194x194><link 
rel=icon type=image/png href=https://apache.org/favicons/favicon-96x96.png 
sizes=96x96><link rel=icon type=image/png 
href=https://apache.org/favicons/android-chrome-192x192.png sizes=192x192><link 
rel=icon type=image/png href=https://apache.org/favicons/favicon-16x16.png 
sizes=16x16><link rel=manifest 
href=https://apache.org/favicons/manifest.json><link rel="shortcut icon" 
href=https://apache.org/favicons/favicon.ico><title>Specification | Apache 
Avro</title><meta name=description content
 ><meta property="og:title" content="Specification"><meta 
 >property="og:description" content><meta property="og:type" 
 >content="website"><meta property="og:url" 
 >content="/docs/1.11.3/specification/"><meta itemprop=name 
 >content="Specification"><meta itemprop=description content><meta 
 >name=twitter:card content="summary"><meta name=twitter:title 
 >content="Specification"><meta name=twitter:description content><link 
 >rel=preload 
 >href=/scss/main.min.e6198ccfb5f488caccc5f70e1d5d01bec7ba61523a1be10b1acc6ce8c9358f56.css
 > as=style><link 
 >href=/scss/main.min.e6198ccfb5f488caccc5f70e1d5d01bec7ba61523a1be10b1acc6ce8c9358f56.css
 > rel=stylesheet integrity><script 
 >src=https://code.jquery.com/jquery-3.5.1.min.js 
 >integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" 
 >crossorigin=anonymous></script>
+<link rel=stylesheet href=/css/prism.css></head><body 
class=td-section><header><nav class="js-navbar-scroll navbar navbar-expand 
navbar-dark flex-column flex-md-row td-navbar"><a class=navbar-brand 
href=/><span class=navbar-logo><img src=/docs/1.11.3/logo.svg width=100 
height=30 style="margin:0 10px"></span><span class="text-uppercase 
font-weight-bold">Apache Avro</span></a><div class="td-navbar-nav-scroll 
ml-md-auto" id=main_navbar><ul class="navbar-nav mt-2 mt-lg-0"><li 
class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link 
href=/project/><span>Project</span></a></li><li class="nav-item mr-4 mb-2 
mb-lg-0"><a class=nav-link href=/blog/><span>Blog</span></a></li><li 
class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link 
href=/community/><span>Community</span></a></li><li class="nav-item dropdown 
mr-4 d-none d-lg-block"><a class="nav-link dropdown-toggle" href=# 
id=navbarDropdown role=button data-toggle=dropdown aria-haspopup=true 
aria-expanded=false>Documentation</a><div class=dropdown-
 menu aria-labelledby=navbarDropdownMenuLink><a class=dropdown-item 
href=/docs/1.11.3/>1.11.3 (Current)</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.11.0/>1.11.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.10.2/>1.10.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.10.1/>1.10.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.10.0/>1.10.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.9.2/>1.9.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.9.1/>1.9.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.9.0/>1.9.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.8.2/>1.8.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.8.1/>1.8.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.8.0/>1.8.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.7/>1.7.7</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.6/>1.7.6</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.5/>1.7.5</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.4/>1.7.4</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.3/>1.7.3</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.2/>1.7.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.1/>1.7.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.7.0/>1.7.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.6.3/>1.6.3</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.6.2/>1.6.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.6.1/>1.6.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.6.0/>1.6.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.5.4/>1.5.4</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.5.3/>1.5.3</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.5.2/>1.5.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.5.1/>1.5.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.5.0/>1.5.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.4.1/>1.4.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.4.0/>1.4.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.3.3/>1.3.3</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.3.2/>1.3.2</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.3.1/>1.3.1</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.3.0/>1.3.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.2.0/>1.2.0</a>
+<a class=dropdown-item href=https://avro.apache.org/docs/1.1.0/>1.1.0</a>
+<a class=dropdown-item 
href=https://avro.apache.org/docs/1.0.0/>1.0.0</a></div></li></ul></div><div 
class="navbar-nav d-none d-lg-block"></div></nav></header><div 
class="container-fluid td-outer"><div class=td-main><div class="row 
flex-xl-nowrap"><main class="col-12 col-md-9 col-xl-8 pl-md-5" role=main><div 
class=td-content><div class="pageinfo pageinfo-primary d-print-none"><p>This is 
the multi-page printable view of this section.
+<a href=# onclick="return print(),!1">Click here to print</a>.</p><p><a 
href=/docs/1.11.3/specification/>Return to the regular view of this 
page</a>.</p></div><h1 class=title>Specification</h1><ul></ul><div 
class=content><h2 id=introduction>Introduction</h2><p>This document defines 
Apache Avro. It is intended to be the authoritative specification. 
Implementations of Avro must adhere to this document.</p><h2 
id=schema-declaration>Schema Declaration</h2><p>A Schema is represented in <a 
href=https://www.json.org/>JSON</a> by one of:</p><ul><li>A JSON string, naming 
a defined type.</li><li>A JSON object, of the form:</li></ul><div 
class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-js data-lang=js><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#4e9a06>&#34;type&#34;</span><span 
style=color:#ce5c00;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;typeName&#34;<
 /span><span style=color:#000;font-weight:700>,</span> <span 
style=color:#000;font-weight:700>...</span><span 
style=color:#000>attributes</span><span 
style=color:#000;font-weight:700>...}</span>
+</span></span></code></pre></div><p>where <em>typeName</em> is either a 
primitive or derived type name, as defined below. Attributes not defined in 
this document are permitted as metadata, but must not affect the format of 
serialized data.</p><ul><li>A JSON array, representing a union of embedded 
types.</li></ul><h2 id=primitive-types>Primitive Types</h2><p>The set of 
primitive type names is:</p><ul><li><em>null</em>: no 
value</li><li><em>boolean</em>: a binary value</li><li><em>int</em>: 32-bit 
signed integer</li><li><em>long</em>: 64-bit signed 
integer</li><li><em>float</em>: single precision (32-bit) IEEE 754 
floating-point number</li><li><em>double</em>: double precision (64-bit) IEEE 
754 floating-point number</li><li><em>bytes</em>: sequence of 8-bit unsigned 
bytes</li><li><em>string</em>: unicode character sequence</li></ul><p>Primitive 
types have no specified attributes.</p><p>Primitive type names are also defined 
type names. Thus, for example, the schema &ldquo;string&rdquo;
  is equivalent to:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><h2 id=complex-types>Complex 
Types</h2><p>Avro supports six kinds of complex types: <em>records</em>, 
<em>enums</em>, <em>arrays</em>, <em>maps</em>, <em>unions</em> and 
<em>fixed</em>.</p><h3 id=schema-record>Records</h3><p>Records use the type 
name &ldquo;record&rdquo; and support the following 
attributes:</p><ul><li><em>name</em>: a JSON string providing the name of the 
record (required).</li><li><em>namespace</em>, a JSON string that qualifies the 
name (optional);</li><li><em>doc</em>: a JSON string providing documentation to 
the user of this schema (optional).</li><li><em>aliases</em>: a JSON array of 
strings, providing alternate names for this record 
(optional).</li><li><em>fields</em>: a JSON array, listing fields (required). 
Each field is a JSON object with the following 
attributes:<ul><li><em>name</em>: a JSON string providing the name of the field 
(required), and</li><li><em>doc</em>: a JSON string describing this field for 
users (optional)
 .</li><li><em>type</em>: a <a href=#schema-declaration title="Schema 
declaration">schema</a>, as defined above</li><li><em>order</em>: specifies how 
this field impacts sort ordering of this record (optional). Valid values are 
&ldquo;ascending&rdquo; (the default), &ldquo;descending&rdquo;, or 
&ldquo;ignore&rdquo;. For more details on how this is used, see the sort order 
section below.</li><li><em>aliases</em>: a JSON array of strings, providing 
alternate names for this field (optional).</li><li><em>default</em>: A default 
value for this field, only used when reading instances that lack the field for 
schema evolution purposes. The presence of a default value does not make the 
field optional at encoding time. Permitted values depend on the field&rsquo;s 
schema type, according to the table below. Default values for union fields 
correspond to the first schema in the union. Default values for bytes and fixed 
fields are JSON strings, where Unicode code points 0-255 are mapped to unsigned 
 8-bit byte values 0-255. Avro encodes a field even if its value is equal to 
its default.</li></ul></li></ul><p><em>field default 
values</em></p><table><thead><tr><th><strong>avro 
type</strong></th><th><strong>json 
type</strong></th><th><strong>example</strong></th></tr></thead><tbody><tr><td>null</td><td>null</td><td><code>null</code></td></tr><tr><td>boolean</td><td>boolean</td><td><code>true</code></td></tr><tr><td>int,long</td><td>integer</td><td><code>1</code></td></tr><tr><td>float,double</td><td>number</td><td><code>1.1</code></td></tr><tr><td>bytes</td><td>string</td><td><code>"\u00FF"</code></td></tr><tr><td>string</td><td>string</td><td><code>"foo"</code></td></tr><tr><td>record</td><td>object</td><td><code>{"a":
 
1}</code></td></tr><tr><td>enum</td><td>string</td><td><code>"FOO"</code></td></tr><tr><td>array</td><td>array</td><td><code>[1]</code></td></tr><tr><td>map</td><td>object</td><td><code>{"a":
 1}</code></td></tr><tr><td>fixed</td><td>string</td><td><code>"\u00ff"</c
 ode></td></tr></tbody></table><p>For example, a linked-list of 64-bit values 
may be defined with:</p><pre tabindex=0><code class=language-jsonc 
data-lang=jsonc>{
+  &#34;type&#34;: &#34;record&#34;,
+  &#34;name&#34;: &#34;LongList&#34;,
+  &#34;aliases&#34;: [&#34;LinkedLongs&#34;],                      // old name 
for this
+  &#34;fields&#34; : [
+    {&#34;name&#34;: &#34;value&#34;, &#34;type&#34;: &#34;long&#34;},         
    // each element has a long
+    {&#34;name&#34;: &#34;next&#34;, &#34;type&#34;: [&#34;null&#34;, 
&#34;LongList&#34;]} // optional next element
+  ]
+}
+</code></pre><h3 id=enums>Enums</h3><p>Enums use the type name 
&ldquo;enum&rdquo; and support the following 
attributes:</p><ul><li><em>name</em>: a JSON string providing the name of the 
enum (required).</li><li><em>namespace</em>, a JSON string that qualifies the 
name (optional);</li><li><em>aliases</em>: a JSON array of strings, providing 
alternate names for this enum (optional).</li><li><em>doc</em>: a JSON string 
providing documentation to the user of this schema 
(optional).</li><li><em>symbols</em>: a JSON array, listing symbols, as JSON 
strings (required). All symbols in an enum must be unique; duplicates are 
prohibited. Every symbol must match the regular expression 
[A-Za-z_][A-Za-z0-9_]* (the same requirement as for <a href=#names 
title=Names>names</a>).</li><li><em>default</em>: A default value for this 
enumeration, used during resolution when the reader encounters a symbol from 
the writer that isn&rsquo;t defined in the reader&rsquo;s schema (optional). 
The value provided h
 ere must be a JSON string that&rsquo;s a member of the symbols array. See 
documentation on schema resolution for how this gets used.</li></ul><p>For 
example, playing card suits might be defined with:</p><div class=highlight><pre 
tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;enum&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Suit&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;symbols&#34;</span> <span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;SPADES&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;HEARTS&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;DIAMONDS&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;CLUBS&#34;</span><span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><h3 id=arrays>Arrays</h3><p>Arrays use the 
type name &ldquo;array&rdquo; and support a single 
attribute:</p><ul><li><em>items</em>: the schema of the array&rsquo;s 
items.</li></ul><p>For example, an array of strings is declared with:</p><div 
class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;array&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;items&#34;</span> <span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;default&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><h3 id=maps>Maps</h3><p>Maps use the type 
name &ldquo;map&rdquo; and support one attribute:</p><ul><li><em>values</em>: 
the schema of the map&rsquo;s values.</li></ul><p>Map keys are assumed to be 
strings.</p><p>For example, a map from string to long is declared with:</p><div 
class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;map&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;values&#34;</span> <span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;long&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;default&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{}</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><h3 id=unions>Unions</h3><p>Unions, as 
mentioned above, are represented using JSON arrays. For example, <code>["null", 
"string"]</code> declares a schema which may be either a null or 
string.</p><p>(Note that when a <a href=#schema-record title="Schema 
record">default value</a> is specified for a record field whose type is a 
union, the type of the default value must match the first element of the union. 
Thus, for unions containing &ldquo;null&rdquo;, the &ldquo;null&rdquo; is 
usually listed first, since the default value of such unions is typically 
null.)</p><p>Unions may not contain more than one schema with the same type, 
except for the named types record, fixed and enum. For example, unions 
containing two array types or two map types are not permitted, but two types 
with different names are permitted. (Names permit efficient resolution when 
reading and writing unions.)</p><p>Unions may not immediately contain other 
unions.</p><h3 id=fixed>Fixed</h
 3><p>Fixed uses the type name &ldquo;fixed&rdquo; and supports the following 
attributes:</p><ul><li><em>name</em>: a string naming this fixed 
(required).</li><li><em>namespace</em>, a string that qualifies the name 
(optional);</li><li><em>aliases</em>: a JSON array of strings, providing 
alternate names for this enum (optional).</li><li><em>size</em>: an integer, 
specifying the number of bytes per value (required).</li></ul><p>For example, 
16-byte quantity may be declared with:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;fixed&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;size&#34;</span><span style=co
 lor:#000;font-weight:700>:</span> <span 
style=color:#0000cf;font-weight:700>16</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;md5&#34;</span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><h3 id=names>Names</h3><p>Record, enums and 
fixed are named types. Each has a fullname that is composed of two parts; a 
name and a namespace, separated by a dot. Equality of names is defined on the 
fullname.</p><p>Record fields and enum symbols have names as well (but no 
namespace). Equality of fields and enum symbols is defined on the name of the 
field/symbol within its scope (the record/enum that defines it). Fields and 
enum symbols across scopes are never equal.</p><p>The name portion of the 
fullname of named types, record field names, and enum symbols 
must:</p><ul><li>start with [A-Za-z_]</li><li>subsequently contain only 
[A-Za-z0-9_]</li></ul><p>A namespace is a dot-separated sequence of such names. 
The empty string may also be used as a namespace to indicate the null 
namespace. Equality of names (including field names and enum symbols) as well 
as fullnames is case-sensitive.</p><p>The null namespace may not be used in a 
dot-separated sequence o
 f names. So the grammar for a namespace is:</p><pre tabindex=0><code>  
&lt;empty&gt; | &lt;name&gt;[(&lt;dot&gt;&lt;name&gt;)*]
+</code></pre><p>In record, enum and fixed definitions, the fullname is 
determined according to the algorithm below the example:</p><pre 
tabindex=0><code>{
+  &#34;type&#34;: &#34;record&#34;,
+  &#34;name&#34;: &#34;Example&#34;,
+  &#34;doc&#34;: &#34;A simple name (attribute) and no namespace attribute: 
use the null namespace (\&#34;\&#34;); the fullname is &#39;Example&#39;.&#34;,
+  &#34;fields&#34;: [
+    {
+      &#34;name&#34;: &#34;inheritNull&#34;,
+      &#34;type&#34;: {
+        &#34;type&#34;: &#34;enum&#34;,
+        &#34;name&#34;: &#34;Simple&#34;,
+        &#34;doc&#34;: &#34;A simple name (attribute) and no namespace 
attribute: inherit the null namespace of the enclosing type &#39;Example&#39;. 
The fullname is &#39;Simple&#39;.&#34;,
+        &#34;symbols&#34;: [&#34;a&#34;, &#34;b&#34;]
+      }
+    }, {
+      &#34;name&#34;: &#34;explicitNamespace&#34;,
+      &#34;type&#34;: {
+        &#34;type&#34;: &#34;fixed&#34;,
+        &#34;name&#34;: &#34;Simple&#34;,
+        &#34;namespace&#34;: &#34;explicit&#34;,
+        &#34;doc&#34;: &#34;A simple name (attribute) and a namespace 
(attribute); the fullname is &#39;explicit.Simple&#39; (this is a different 
type than of the &#39;inheritNull&#39; field).&#34;,
+        &#34;size&#34;: 12
+      }
+    }, {
+      &#34;name&#34;: &#34;fullName&#34;,
+      &#34;type&#34;: {
+        &#34;type&#34;: &#34;record&#34;,
+        &#34;name&#34;: &#34;a.full.Name&#34;,
+        &#34;namespace&#34;: &#34;ignored&#34;,
+        &#34;doc&#34;: &#34;A name attribute with a fullname, so the namespace 
attribute is ignored. The fullname is &#39;a.full.Name&#39;, and the namespace 
is &#39;a.full&#39;.&#34;,
+        &#34;fields&#34;: [
+          {
+            &#34;name&#34;: &#34;inheritNamespace&#34;,
+            &#34;type&#34;: {
+              &#34;type&#34;: &#34;enum&#34;,
+              &#34;name&#34;: &#34;Understanding&#34;,
+              &#34;doc&#34;: &#34;A simple name (attribute) and no namespace 
attribute: inherit the namespace of the enclosing type &#39;a.full.Name&#39;. 
The fullname is &#39;a.full.Understanding&#39;.&#34;,
+              &#34;symbols&#34;: [&#34;d&#34;, &#34;e&#34;]
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
+</code></pre><p>The fullname of a record, enum or fixed definition is 
determined by the required <code>name</code> and optional 
<code>namespace</code> attributes like this:</p><ul><li>A fullname is 
specified. If the name specified contains a dot, then it is assumed to be a 
fullname, and any namespace also specified is ignored. For example, use 
&ldquo;name&rdquo;: &ldquo;org.foo.X&rdquo; to indicate the fullname 
org.foo.X.</li><li>A simple name (a name that contains no dots) and namespace 
are both specified. For example, one might use &ldquo;name&rdquo;: 
&ldquo;X&rdquo;, &ldquo;namespace&rdquo;: &ldquo;org.foo&rdquo; to indicate the 
fullname org.foo.X.</li><li>A simple name only is specified (a name that 
contains no dots). In this case the namespace is taken from the most tightly 
enclosing named schema or protocol, and the fullname is constructed from that 
namespace and the name. For example, if &ldquo;name&rdquo;: &ldquo;X&rdquo; is 
specified, and this occurs within a field of the r
 ecord definition of org.foo.Y, then the fullname is org.foo.X. This also 
happens if there is no enclosing namespace (i.e., the enclosing schema 
definition has the null namespace).</li></ul><p>References to previously 
defined names are as in the latter two cases above: if they contain a dot they 
are a fullname, if they do not contain a dot, the namespace is the namespace of 
the enclosing definition.</p><p>Primitive type names (<code>null</code>, 
<code>boolean</code>, <code>int</code>, <code>long</code>, <code>float</code>, 
<code>double</code>, <code>bytes</code>, <code>string</code>) have no namespace 
and their names may not be defined in any namespace.</p><p>Complex types 
(<code>record</code>, <code>enum</code>, <code>array</code>, <code>map</code>, 
<code>fixed</code>) have no namespace, but their names (as well as 
<code>union</code>) are permitted to be reused as type names. This can be 
confusing to the human reader, but is always unambiguous for binary 
serialization. Due to the li
 mitations of JSON encoding, it is a best practice to use a namespace when 
using these names.</p><p>A schema or protocol may not contain multiple 
definitions of a fullname. Further, a name must be defined before it is used 
(&ldquo;before&rdquo; in the depth-first, left-to-right traversal of the JSON 
parse tree, where the types attribute of a protocol is always deemed to come 
&ldquo;before&rdquo; the messages attribute.)</p><h3 
id=aliases>Aliases</h3><p>Named types and fields may have aliases. An 
implementation may optionally use aliases to map a writer&rsquo;s schema to the 
reader&rsquo;s. This facilitates both schema evolution as well as processing 
disparate datasets.</p><p>Aliases function by re-writing the writer&rsquo;s 
schema using aliases from the reader&rsquo;s schema. For example, if the 
writer&rsquo;s schema was named &ldquo;Foo&rdquo; and the reader&rsquo;s schema 
is named &ldquo;Bar&rdquo; and has an alias of &ldquo;Foo&rdquo;, then the 
implementation would act as though &
 ldquo;Foo&rdquo; were named &ldquo;Bar&rdquo; when reading. Similarly, if data 
was written as a record with a field named &ldquo;x&rdquo; and is read as a 
record with a field named &ldquo;y&rdquo; with alias &ldquo;x&rdquo;, then the 
implementation would act as though &ldquo;x&rdquo; were named &ldquo;y&rdquo; 
when reading.</p><p>A type alias may be specified either as a fully 
namespace-qualified, or relative to the namespace of the name it is an alias 
for. For example, if a type named &ldquo;a.b&rdquo; has aliases of 
&ldquo;c&rdquo; and &ldquo;x.y&rdquo;, then the fully qualified names of its 
aliases are &ldquo;a.c&rdquo; and &ldquo;x.y&rdquo;.</p><h2 
id=data-serialization-and-deserialization>Data Serialization and 
Deserialization</h2><p>Binary encoded Avro data does not include type 
information or field names. The benefit is that the serialized data is small, 
but as a result a schema must always be used in order to read Avro data 
correctly. The best way to ensure that the schema i
 s structurally identical to the one used to write the data is to use the exact 
same schema.</p><p>Therefore, files or systems that store Avro data should 
always include the writer&rsquo;s schema for that data. Avro-based remote 
procedure call (RPC) systems must also guarantee that remote recipients of data 
have a copy of the schema used to write that data. In general, it is advisable 
that any reader of Avro data should use a schema that is the same (as defined 
more fully in <a href=#parsing-canonical-form-for-schemas title="Parsing 
Canonical Form for Schemas">Parsing Canonical Form for Schemas</a>) as the 
schema that was used to write the data in order to deserialize it correctly. 
Deserializing data into a newer schema is accomplished by specifying an 
additional schema, the results of which are described in <a 
href=#schema-resolution>Schema Resolution</a>.</p><p>In general, both 
serialization and deserialization proceed as a depth-first, left-to-right 
traversal of the schema, serial
 izing or deserializing primitive types as they are encountered. Therefore, it 
is possible, though not advisable, to read Avro data with a schema that does 
not have the same Parsing Canonical Form as the schema with which the data was 
written. In order for this to work, the serialized primitive values must be 
compatible, in order value by value, with the items in the deserialization 
schema. For example, int and long are always serialized the same way, so an int 
could be deserialized as a long. Since the compatibility of two schemas depends 
on both the data and the serialization format (eg. binary is more permissive 
than JSON because JSON includes field names, eg. a long that is too large will 
overflow an int), it is simpler and more reliable to use schemas with identical 
Parsing Canonical Form.</p><h3 id=encodings>Encodings</h3><p>Avro specifies two 
serialization encodings: binary and JSON. Most applications will use the binary 
encoding, as it is smaller and faster. But, for debuggin
 g and web-based applications, the JSON encoding may sometimes be 
appropriate.</p><h3 id=binary-encoding>Binary Encoding</h3><p>Binary encoding 
does not include field names, self-contained information about the types of 
individual bytes, nor field or record separators. Therefore readers are wholly 
reliant on the schema used when the data was encoded.</p><h4 
id=primitive-types-1>Primitive Types</h4><p>Primitive types are encoded in 
binary as follows:</p><ul><li><em>null</em> is written as zero bytes.</li><li>a 
<em>boolean</em> is written as a single byte whose value is either 0 (false) or 
1 (true).</li><li><em>int</em> and <em>long</em> values are written using <a 
href=https://lucene.apache.org/java/3_5_0/fileformats.html#VInt>variable-length</a>
 <a 
href=https://code.google.com/apis/protocolbuffers/docs/encoding.html#types>zig-zag</a>
 coding. Some 
examples:</li></ul><table><thead><tr><th><em>value</em></th><th><em>hex</em></th></tr></thead><tbody><tr><td>0</td><td>00</td></tr><tr><td>
 
-1</td><td>01</td></tr><tr><td>1</td><td>02</td></tr><tr><td>-2</td><td>03</td></tr><tr><td>2</td><td>04</td></tr><tr><td>&mldr;</td><td>&mldr;</td></tr><tr><td>-64</td><td>7f</td></tr><tr><td>64</td><td>80
 01</td></tr><tr><td>&mldr;</td><td>&mldr;</td></tr></tbody></table><ul><li>a 
<em>float</em> is written as 4 bytes. The float is converted into a 32-bit 
integer using a method equivalent to Java&rsquo;s <a 
href=https://docs.oracle.com/javase/8/docs/api/java/lang/Float.html#floatToIntBits-float->floatToIntBits</a>
 and then encoded in little-endian format.</li><li>a <em>double</em> is written 
as 8 bytes. The double is converted into a 64-bit integer using a method 
equivalent to Java&rsquo;s <a 
href=https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#doubleToLongBits-double->doubleToLongBits</a>
 and then encoded in little-endian format.</li><li><em>bytes</em> are encoded 
as a long followed by that many bytes of data.</li><li>a <em>string</em> is 
encoded as a long followed
  by that many bytes of UTF-8 encoded character data.
+For example, the three-character string &ldquo;foo&rdquo; would be encoded as 
the long value 3 (encoded as hex 06) followed by the UTF-8 encoding of 
&lsquo;f&rsquo;, &lsquo;o&rsquo;, and &lsquo;o&rsquo; (the hex bytes 66 6f 
6f):</li></ul><pre tabindex=0><code>06 66 6f 6f
+</code></pre><h3 id=complex-types-1>Complex Types</h3><p>Complex types are 
encoded in binary as follows:</p><h4 id=records>Records</h4><p>A record is 
encoded by encoding the values of its fields in the order that they are 
declared. In other words, a record is encoded as just the concatenation of the 
encodings of its fields. Field values are encoded per their schema.</p><p>For 
example, the record schema</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;record&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;test&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span> <span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;a&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;long&#34;</span><span 
style=color:#000;font-weight:700>},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;b&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><p>An instance of this record whose a field 
has value 27 (encoded as hex 36) and whose b field has value &ldquo;foo&rdquo; 
(encoded as hex bytes 06 66 6f 6f), would be encoded simply as the 
concatenation of these, namely the hex byte sequence:</p><pre 
tabindex=0><code>36 06 66 6f 6f
+</code></pre><h4 id=enums-1>Enums</h4><p>An enum is encoded by a int, 
representing the zero-based position of the symbol in the schema.</p><p>For 
example, consider the enum:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;enum&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Foo&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;symbols&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span style=color:#4
 e9a06>&#34;A&#34;</span><span style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;B&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;C&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;D&#34;</span><span 
style=color:#000;font-weight:700>]</span> <span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><p>This would be encoded by an int between 
zero and three, with zero indicating &ldquo;A&rdquo;, and 3 indicating 
&ldquo;D&rdquo;.</p><h4 id=arrays-1>Arrays</h4><p>Arrays are encoded as a 
series of blocks. Each block consists of a long count value, followed by that 
many array items. A block with count zero indicates the end of the array. Each 
item is encoded per the array&rsquo;s item schema.</p><p>If a block&rsquo;s 
count is negative, its absolute value is used, and the count is followed 
immediately by a long block size indicating the number of bytes in the block. 
This block size permits fast skipping through data, e.g., when projecting a 
record to a subset of its fields.</p><p>For example, the array schema</p><div 
class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span style=col
 or:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;array&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;items&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;long&#34;</span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><p>an array containing the items 3 and 27 
could be encoded as the long value 2 (encoded as hex 04) followed by long 
values 3 and 27 (encoded as hex 06 36) terminated by zero:</p><pre 
tabindex=0><code>04 06 36 00
+</code></pre><p>The blocked representation permits one to read and write 
arrays larger than can be buffered in memory, since one can start writing items 
without knowing the full length of the array.</p><h4 
id=schema-maps>Maps</h4><p>Maps are encoded as a series of <em>blocks</em>. 
Each block consists of a <code>long</code> <em>count</em> value, followed by 
that many key/value pairs. A block with count zero indicates the end of the 
map. Each item is encoded per the map&rsquo;s value schema.</p><p>If a 
block&rsquo;s count is negative, its absolute value is used, and the count is 
followed immediately by a <code>long</code> block size indicating the number of 
bytes in the block. This block size permits fast skipping through data, e.g., 
when projecting a record to a subset of its fields.</p><p>The blocked 
representation permits one to read and write maps larger than can be buffered 
in memory, since one can start writing items without knowing the full length of 
the map.</p><h4 id=unions-1
 >Unions</h4><p>A union is encoded by first writing an <code>int</code> value 
 >indicating the zero-based position within the union of the schema of its 
 >value. The value is then encoded per the indicated schema within the 
 >union.</p><p>For example, the union schema <code>["null","string"]</code> 
 >would encode:</p><ul><li><em>null</em> as zero (the index of 
 >&ldquo;null&rdquo; in the union):
+<code>00</code></li><li>the string &ldquo;a&rdquo; as one (the index of 
&ldquo;string&rdquo; in the union, 1, encoded as hex 02), followed by the 
serialized string:
+<code>02 02 61</code>
+NOTE: Currently for C/C++ implementations, the positions are practically an 
int, but theoretically a long. In reality, we don&rsquo;t expect unions with 
215M members</li></ul><h4 id=fixed-1>Fixed</h4><p>Fixed instances are encoded 
using the number of bytes declared in the schema.</p><h3 id=json-encoding>JSON 
Encoding</h3><p>Except for unions, the JSON encoding is the same as is used to 
encode <a href=#schema-record>field default values</a>.</p><p>The value of a 
union is encoded in JSON as follows:</p><ul><li>if its type is <em>null</em>, 
then it is encoded as a JSON <em>null</em>;</li><li>otherwise it is encoded as 
a JSON object with one name/value pair whose name is the type&rsquo;s name and 
whose value is the recursively encoded value. For Avro&rsquo;s named types 
(record, fixed or enum) the user-specified name is used, for other types the 
type name is used.</li></ul><p>For example, the union schema 
<code>["null","string","Foo"]</code>, where Foo is a record name, would 
encode:</p
 ><ul><li><em>null</em> as <em>null</em>;</li><li>the string &ldquo;a&rdquo; as 
 ><code>{"string": "a"}</code> and</li><li>a Foo instance as <code>{"Foo": 
 >{...}}</code>, where <code>{...}</code> indicates the JSON encoding of a Foo 
 >instance.</li></ul><p>Note that the original schema is still required to 
 >correctly process JSON-encoded data. For example, the JSON encoding does not 
 >distinguish between <em>int</em> and <em>long</em>, <em>float</em> and 
 ><em>double</em>, records and maps, enums and strings, etc.</p><h3 
 >id=single-object-encoding>Single-object encoding</h3><p>In some situations a 
 >single Avro serialized object is to be stored for a longer period of time. 
 >One very common example is storing Avro records for several weeks in an <a 
 >href=https://kafka.apache.org/>Apache Kafka</a> topic.</p><p>In the period 
 >after a schema change this persistence system will contain records that have 
 >been written with different schemas. So the need arises to know which schema 
 >was used to write a recor
 d to support schema evolution correctly. In most cases the schema itself is 
too large to include in the message, so this binary wrapper format supports the 
use case more effectively.</p><h4 
id=single-object-encoding-specification>Single object encoding 
specification</h4><p>Single Avro objects are encoded as follows:</p><ol><li>A 
two-byte marker, <code>C3 01</code>, to show that the message is Avro and uses 
this single-record format (version 1).</li><li>The 8-byte little-endian 
CRC-64-AVRO <a href=#schema-fingerprints title="Schema 
fingerprints">fingerprint</a> of the object&rsquo;s schema.</li><li>The Avro 
object encoded using <a href=#binary-encoding>Avro&rsquo;s binary 
encoding</a>.</li></ol><p>Implementations use the 2-byte marker to determine 
whether a payload is Avro. This check helps avoid expensive lookups that 
resolve the schema from a fingerprint, when the message is not an encoded Avro 
payload.</p><h2 id=sort-order>Sort Order</h2><p>Avro defines a standard sort 
order for d
 ata. This permits data written by one system to be efficiently sorted by 
another system. This can be an important optimization, as sort order 
comparisons are sometimes the most frequent per-object operation. Note also 
that Avro binary-encoded data can be efficiently ordered without deserializing 
it to objects.</p><p>Data items may only be compared if they have identical 
schemas. Pairwise comparisons are implemented recursively with a depth-first, 
left-to-right traversal of the schema. The first mismatch encountered 
determines the order of the items.</p><p>Two items with the same schema are 
compared according to the following rules.</p><ul><li><em>null</em> data is 
always equal.</li><li><em>boolean</em> data is ordered with false before 
true.</li><li><em>int</em>, <em>long</em>, <em>float</em> and <em>double</em> 
data is ordered by ascending numeric value.</li><li><em>bytes</em> and fixed 
data are compared lexicographically by unsigned 8-bit 
values.</li><li><em>string</em> data is co
 mpared lexicographically by Unicode code point. Note that since UTF-8 is used 
as the binary encoding for strings, sorting of bytes and string binary data is 
identical.</li><li><em>array</em> data is compared lexicographically by 
element.</li><li><em>enum</em> data is ordered by the symbol&rsquo;s position 
in the enum schema. For example, an enum whose symbols are <code>["z", 
"a"]</code> would sort &ldquo;z&rdquo; values before &ldquo;a&rdquo; 
values.</li><li><em>union</em> data is first ordered by the branch within the 
union, and, within that, by the type of the branch. For example, an 
<code>["int", "string"]</code> union would order all int values before all 
string values, with the ints and strings themselves ordered as defined 
above.</li><li><em>record</em> data is ordered lexicographically by field. If a 
field specifies that its order is:<ul><li>&ldquo;ascending&rdquo;, then the 
order of its values is unaltered.</li><li>&ldquo;descending&rdquo;, then the 
order of its values is re
 versed.</li><li>&ldquo;ignore&rdquo;, then its values are ignored when 
sorting.</li></ul></li><li><em>map</em> data may not be compared. It is an 
error to attempt to compare data containing maps unless those maps are in an 
<code>"order":"ignore"</code> record field.</li></ul><h2 
id=object-container-files>Object Container Files</h2><p>Avro includes a simple 
object container file format. A file has a schema, and all objects stored in 
the file must be written according to that schema, using binary encoding. 
Objects are stored in blocks that may be compressed. Syncronization markers are 
used between blocks to permit efficient splitting of files for MapReduce 
processing.</p><p>Files may include arbitrary user-specified metadata.</p><p>A 
file consists of:</p><ul><li>A file header, followed by</li><li>one or more 
file data blocks.</li></ul><p>A file header consists of:</p><ul><li>Four bytes, 
ASCII &lsquo;O&rsquo;, &lsquo;b&rsquo;, &lsquo;j&rsquo;, followed by 
1.</li><li>file metadata, incl
 uding the schema.</li><li>The 16-byte, randomly-generated sync marker for this 
file.</li></ul><p>File metadata is written as if defined by the following <a 
href=#schema-maps>map</a> schema:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;map&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;values&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;bytes&#34;</span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><p>All metadata properties that start with 
&ldquo;avro.&rdquo; are reserved. The following file metadata properties are 
currently used:</p><ul><li><strong>avro.schema</strong> contains the schema of 
objects stored in the file, as JSON data 
(required).</li><li><strong>avro.codec</strong> the name of the compression 
codec used to compress blocks, as a string. Implementations are required to 
support the following codecs: &ldquo;null&rdquo; and &ldquo;deflate&rdquo;. If 
codec is absent, it is assumed to be &ldquo;null&rdquo;. The codecs are 
described with more detail below.</li></ul><p>A file header is thus described 
by the following schema:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;f
 ont-weight:700>:</span> <span style=color:#4e9a06>&#34;record&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;org.apache.avro.file.Header&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span> <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span> <span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>   <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;magic&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;fixed&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Magic&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;size&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span style=
 color:#0000cf;font-weight:700>4</span><span 
style=color:#000;font-weight:700>}},</span>
+</span></span><span style=display:flex><span>   <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;meta&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;map&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;values&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;bytes&#34;</span><span 
style=color:#000;font-weight:700>}},</span>
+</span></span><span style=display:flex><span>   <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;sync&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;fixed&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Sync&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;size&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span style=co
 lor:#0000cf;font-weight:700>16</span><span 
style=color:#000;font-weight:700>}}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><p>A file data block consists 
of:</p><ul><li>A long indicating the count of objects in this block.</li><li>A 
long indicating the size in bytes of the serialized objects in the current 
block, after any codec is applied</li><li>The serialized objects. If a codec is 
specified, this is compressed by that codec.</li><li>The file&rsquo;s 16-byte 
sync marker.</li></ul><p>A file data block is thus described by the following 
schema:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;record&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight
 :700>:</span> <span 
style=color:#4e9a06>&#34;org.apache.avro.file.DataBlock&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span> <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span> <span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>   <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;count&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;long&#34;</span><span 
style=color:#000;font-weight:700>},</span>
+</span></span><span style=display:flex><span>   <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;data&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;bytes&#34;</span><span 
style=color:#000;font-weight:700>},</span>
+</span></span><span style=display:flex><span>   <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;sync&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;fixed&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Sync&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;size&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span style=co
 lor:#0000cf;font-weight:700>16</span><span 
style=color:#000;font-weight:700>}}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><p>Each block&rsquo;s binary data can be 
efficiently extracted or skipped without deserializing the contents. The 
combination of block size, object counts, and sync markers enable detection of 
corrupt blocks and help ensure data integrity.</p><h3 
id=required-codecs>Required Codecs</h3><p><em>null</em></p><p>The 
&ldquo;null&rdquo; codec simply passes through data 
uncompressed.</p><p><em>deflate</em></p><p>The &ldquo;deflate&rdquo; codec 
writes the data block using the deflate algorithm as specified in <a 
href=https://www.isi.edu/in-notes/rfc1951.txt>RFC 1951</a>, and typically 
implemented using the zlib library. Note that this format (unlike the 
&ldquo;zlib format&rdquo; in RFC 1950) does not have a checksum.</p><h3 
id=optional-codecs>Optional Codecs</h3><p><em>bzip2</em></p><p>The 
&ldquo;bzip2&rdquo; codec uses the <a 
href=https://sourceware.org/bzip2/>bzip2</a> compression 
library.</p><p><em>snappy</em></p><p>The &ldquo;snappy&rdquo; codec uses Goog
 le&rsquo;s <a href=https://code.google.com/p/snappy/>Snappy</a> compression 
library. Each compressed block is followed by the 4-byte, big-endian CRC32 
checksum of the uncompressed data in the block.</p><p><em>xz</em></p><p>The 
&ldquo;xz&rdquo; codec uses the <a href=https://tukaani.org/xz/>XZ</a> 
compression library.</p><p><em>zstandard</em></p><p>The &ldquo;zstandard&rdquo; 
codec uses Facebook&rsquo;s <a 
href=https://facebook.github.io/zstd/>Zstandard</a> compression library.</p><h3 
id=protocol-declaration>Protocol Declaration</h3><p>Avro protocols describe RPC 
interfaces. Like schemas, they are defined with JSON text.</p><p>A protocol is 
a JSON object with the following attributes:</p><ul><li><em>protocol</em>, a 
string, the name of the protocol (required);</li><li><em>namespace</em>, an 
optional string that qualifies the name (optional);</li><li><em>doc</em>, an 
optional string describing this protocol;</li><li><em>types</em>, an optional 
list of definitions of named types (recor
 ds, enums, fixed and errors). An error definition is just like a record 
definition except it uses &ldquo;error&rdquo; instead of &ldquo;record&rdquo;. 
Note that forward references to named types are not 
permitted.</li><li><em>messages</em>, an optional JSON object whose keys are 
message names and whose values are objects whose attributes are described 
below. No two messages may have the same name.</li></ul><p>The name and 
namespace qualification rules defined for schema objects apply to protocols as 
well.</p><h3 id=messages>Messages</h3><p>A message has attributes:</p><ul><li>a 
<em>doc</em>, an optional description of the message,</li><li>a 
<em>request</em>, a list of named, typed parameter schemas (this has the same 
form as the fields of a record declaration);</li><li>a <em>response</em> 
schema;</li><li>an optional union of declared error schemas. The effective 
union has &ldquo;string&rdquo; prepended to the declared union, to permit 
transmission of undeclared &ldquo;system&rdquo; 
 errors. For example, if the declared error union is 
<code>["AccessError"]</code>, then the effective union is <code>["string", 
"AccessError"]</code>. When no errors are declared, the effective error union 
is <code>["string"]</code>. Errors are serialized using the effective union; 
however, a protocol&rsquo;s JSON declaration contains only the declared 
union.</li><li>an optional one-way boolean parameter.</li></ul><p>A request 
parameter list is processed equivalently to an anonymous record. Since record 
field lists may vary between reader and writer, request parameters may also 
differ between the caller and responder, and such differences are resolved in 
the same manner as record field differences.</p><p>The one-way parameter may 
only be true when the response type is <code>"null"</code> and no errors are 
listed.</p><h3 id=sample-protocol>Sample Protocol</h3><p>For example, one may 
define a simple HelloWorld protocol with:</p><div class=highlight><pre 
tabindex=0 style=background-colo
 r:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json 
data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;namespace&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;com.acme&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;protocol&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;HelloWorld&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;doc&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Protocol Greetings&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;types&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Greeting&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;record&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>      <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;message&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>}]},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Curse&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;error&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>      <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;message&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>}]}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>],</span>
+</span></span><span style=display:flex><span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;messages&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#204a87;font-weight:700>&#34;hello&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>      <span 
style=color:#204a87;font-weight:700>&#34;doc&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span style=color:#4e9a06>&#34;Say 
hello.&#34;</span><span style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>      <span 
style=color:#204a87;font-weight:700>&#34;request&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;greeting&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Greeting&#34;</span> <span 
style=color:#000;font-weight:700>}],</span>
+</span></span><span style=display:flex><span>      <span 
style=color:#204a87;font-weight:700>&#34;response&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;Greeting&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>      <span 
style=color:#204a87;font-weight:700>&#34;errors&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;Curse&#34;</span><span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>}</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><h2 id=protocol-wire-format>Protocol Wire 
Format</h2><h3 id=message-transport>Message Transport</h3><p>Messages may be 
transmitted via different transport mechanisms.</p><p>To the transport, a 
<em>message</em> is an opaque byte sequence.</p><p>A transport is a system that 
supports:</p><ul><li><strong>transmission of request 
messages</strong></li><li><strong>receipt of corresponding response 
messages</strong>
+Servers may send a response message back to the client corresponding to a 
request message. The mechanism of correspondence is transport-specific. For 
example, in HTTP it is implicit, since HTTP directly supports requests and 
responses. But a transport that multiplexes many client threads over a single 
socket would need to tag messages with unique 
identifiers.</li></ul><p>Transports may be either stateless or stateful. In a 
stateless transport, messaging assumes no established connection state, while 
stateful transports establish connections that may be used for multiple 
messages. This distinction is discussed further in the <a 
href=#handshake>handshake</a> section below.</p><h4 id=http-as-transport>HTTP 
as Transport</h4><p>When <a 
href=https://www.w3.org/Protocols/rfc2616/rfc2616.html>HTTP</a> is used as a 
transport, each Avro message exchange is an HTTP request/response pair. All 
messages of an Avro protocol should share a single URL at an HTTP server. Other 
protocols may also use 
 that URL. Both normal and error Avro response messages should use the 200 (OK) 
response code. The chunked encoding may be used for requests and responses, 
but, regardless the Avro request and response are the entire content of an HTTP 
request and response. The HTTP Content-Type of requests and responses should be 
specified as &ldquo;avro/binary&rdquo;. Requests should be made using the POST 
method.</p><p>HTTP is used by Avro as a stateless transport.</p><h3 
id=message-framing>Message Framing</h3><p>Avro messages are <em>framed</em> as 
a list of buffers.</p><p>Framing is a layer between messages and the transport. 
It exists to optimize certain operations.</p><p>The format of framed message 
data is:</p><ul><li>a series of buffers, where each buffer consists 
of:<ul><li>a four-byte, big-endian <em>buffer length</em>, followed 
by</li><li>that many bytes of <em>buffer</em> data.</li></ul></li><li>a message 
is always terminated by a zero-length buffer.</li></ul><p>Framing is 
transparent to
  request and response message formats (described below). Any message may be 
presented as a single or multiple buffers.</p><p>Framing can permit readers to 
more efficiently get different buffers from different sources and for writers 
to more efficiently store different buffers to different destinations. In 
particular, it can reduce the number of times large binary objects are copied. 
For example, if an RPC parameter consists of a megabyte of file data, that data 
can be copied directly to a socket from a file descriptor, and, on the other 
end, it could be written directly to a file descriptor, never entering user 
space.</p><p>A simple, recommended, framing policy is for writers to create a 
new segment whenever a single binary object is written that is larger than a 
normal output buffer. Small objects are then appended in buffers, while larger 
objects are written as their own buffers. When a reader then tries to read a 
large object the runtime can hand it an entire buffer directly, wit
 hout having to copy it.</p><h3 id=handshake>Handshake</h3><p>The purpose of 
the handshake is to ensure that the client and the server have each 
other&rsquo;s protocol definition, so that the client can correctly deserialize 
responses, and the server can correctly deserialize requests. Both clients and 
servers should maintain a cache of recently seen protocols, so that, in most 
cases, a handshake will be completed without extra round-trip network exchanges 
or the transmission of full protocol text.</p><p>RPC requests and responses may 
not be processed until a handshake has been completed. With a stateless 
transport, all requests and responses are prefixed by handshakes. With a 
stateful transport, handshakes are only attached to requests and responses 
until a successful handshake response has been returned over a connection. 
After this, request and response payloads are sent without handshakes for the 
lifetime of that connection.</p><p>The handshake process uses the following 
record s
 chemas:</p><div class=highlight><pre tabindex=0 
style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code 
class=language-json data-lang=json><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;record&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;HandshakeRequest&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;namespace&#34;</span><span 
style=color:#000;font-weight:700>:</span><span 
style=color:#4e9a06>&#34;org.apache.avro.ipc&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;clientHash&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>     <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;fixed&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;MD5&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;size&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#0000cf;font-weight:700>16</span><span 
style=color:#000;font-weight:700>}},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;clientProtocol&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;null&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>]},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;serverHash&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;MD5&#34;</span><span 
style=color:#000;font-weight:700>},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;meta&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;null&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;map&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;values&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;bytes&#34;</span><span style=color:#000;font-w
 eight:700>}]}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>{</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;record&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;HandshakeResponse&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;namespace&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;org.apache.avro.ipc&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#204a87;font-weight:700>&#34;fields&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;match&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>     <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;enum&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;HandshakeMatch&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>              <span 
style=color:#204a87;font-weight:700>&#34;symbols&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;BOTH&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;CLIENT&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;NONE&#34;</span><span 
style=color:#000;font-weight:700>]}},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;serverProtocol&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>     <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;null&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#4e9a06>&#34;string&#34;</span><span 
style=color:#000;font-weight:700>]},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;serverHash&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>     <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;null&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;fixed&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;MD5&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;size&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#0000cf;font-weight:700>16</span><span 
style=color:#000;font-weight:700>}]},</span>
+</span></span><span style=display:flex><span>    <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;name&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;meta&#34;</span><span 
style=color:#000;font-weight:700>,</span>
+</span></span><span style=display:flex><span>     <span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#000;font-weight:700>[</span><span 
style=color:#4e9a06>&#34;null&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#000;font-weight:700>{</span><span 
style=color:#204a87;font-weight:700>&#34;type&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;map&#34;</span><span 
style=color:#000;font-weight:700>,</span> <span 
style=color:#204a87;font-weight:700>&#34;values&#34;</span><span 
style=color:#000;font-weight:700>:</span> <span 
style=color:#4e9a06>&#34;bytes&#34;</span><span 
style=color:#000;font-weight:700>}]}</span>
+</span></span><span style=display:flex><span>  <span 
style=color:#000;font-weight:700>]</span>
+</span></span><span style=display:flex><span><span 
style=color:#000;font-weight:700>}</span>
+</span></span></code></pre></div><ul><li>A client first prefixes each request 
with a <code>HandshakeRequest</code> containing just the hash of its protocol 
and of the server&rsquo;s protocol (<code>clientHash!=null, 
clientProtocol=null, serverHash!=null</code>), where the hashes are 128-bit MD5 
hashes of the JSON protocol text. If a client has never connected to a given 
server, it sends its hash as a guess of the server&rsquo;s hash, otherwise it 
sends the hash that it previously obtained from this server.
+The server responds with a HandshakeResponse containing one 
of:<ul><li><code>match=BOTH, serverProtocol=null, serverHash=null</code> if the 
client sent the valid hash of the server&rsquo;s protocol and the server knows 
what protocol corresponds to the client&rsquo;s hash. In this case, the request 
is complete and the response data immediately follows the 
HandshakeResponse.</li><li><code>match=CLIENT, serverProtocol!=null, 
serverHash!=null</code> if the server has previously seen the client&rsquo;s 
protocol, but the client sent an incorrect hash of the server&rsquo;s protocol. 
The request is complete and the response data immediately follows the 
HandshakeResponse. The client must use the returned protocol to process the 
response and should also cache that protocol and its hash for future 
interactions with this server.</li><li><code>match=NONE</code> if the server 
has not previously seen the client&rsquo;s protocol. The serverHash and 
serverProtocol may also be non-null if the server&
 rsquo;s protocol hash was incorrect.
+In this case the client must then re-submit its request with its protocol text 
(<code>clientHash!=null, clientProtocol!=null, serverHash!=null</code>) and the 
server should respond with a successful match (match=BOTH, serverProtocol=null, 
serverHash=null) as above.</li></ul></li></ul><p>The meta field is reserved for 
future handshake enhancements.</p><h3 id=call-format>Call Format</h3><p>A 
<em>call</em> consists of a request message paired with its resulting response 
or error message. Requests and responses contain extensible metadata, and both 
kinds of messages are framed as described above.</p><p>The format of a call 
request is:</p><ul><li><em>request metadata</em>, a map with values of type 
bytes</li><li>the <em>message name</em>, an Avro string, followed 
by</li><li>the <em>message parameters</em>. Parameters are serialized according 
to the message&rsquo;s request declaration.
+When the empty string is used as a message name a server should ignore the 
parameters and return an empty response. A client may use this to ping a server 
or to perform a handshake without sending a protocol message.</li></ul><p>When 
a message is declared one-way and a stateful connection has been established by 
a successful handshake response, no response data is sent. Otherwise the format 
of the call response is:</p><ul><li><em>response metadata</em>, a map with 
values of type bytes</li><li>a one-byte error <em>flag</em> boolean, followed 
by either:<ul><li>if the error flag is false, the message <em>response</em>, 
serialized per the message&rsquo;s response schema.</li><li>if the error flag 
is true, the <em>error</em>, serialized per the message&rsquo;s effective error 
union schema.</li></ul></li></ul><h3 id=schema-resolution>Schema 
Resolution</h3><p>A reader of Avro data, whether from an RPC or a file, can 
always parse that data because the original schema must be provided along 
 with the data. However, the reader may be programmed to read data into a 
different schema. For example, if the data was written with a different version 
of the software than it is read, then fields may have been added or removed 
from records. This section specifies how such schema differences should be 
resolved.</p><p>We refer to the schema used to write the data as the 
writer&rsquo;s schema, and the schema that the application expects the 
reader&rsquo;s schema. Differences between these should be resolved as 
follows:</p><ul><li><p>It is an error if the two schemas do not <em>match</em>.
+To match, one of the following must hold:</p><ul><li>both schemas are arrays 
whose item types match</li><li>both schemas are maps whose value types 
match</li><li>both schemas are enums whose (unqualified) names 
match</li><li>both schemas are fixed whose sizes and (unqualified) names 
match</li><li>both schemas are records with the same (unqualified) 
name</li><li>either schema is a union</li><li>both schemas have same primitive 
type</li><li>the writer&rsquo;s schema may be promoted to the reader&rsquo;s as 
follows:<ul><li>int is promotable to long, float, or double</li><li>long is 
promotable to float or double</li><li>float is promotable to 
double</li><li>string is promotable to bytes</li><li>bytes is promotable to 
string</li></ul></li></ul></li><li><p><strong>if both are 
records</strong>:</p><ul><li>the ordering of fields may be different: fields 
are matched by name.</li><li>schemas for fields with the same name in both 
records are resolved recursively.</li><li>if the writer&rsquo;s 
 record contains a field with a name not present in the reader&rsquo;s record, 
the writer&rsquo;s value for that field is ignored.</li><li>if the 
reader&rsquo;s record schema has a field that contains a default value, and 
writer&rsquo;s schema does not have a field with the same name, then the reader 
should use the default value from its field.</li><li>if the reader&rsquo;s 
record schema has a field with no default value, and writer&rsquo;s schema does 
not have a field with the same name, an error is 
signalled.</li></ul></li><li><p><strong>if both are enums</strong>:
+if the writer&rsquo;s symbol is not present in the reader&rsquo;s enum and the 
reader has a default value, then that value is used, otherwise an error is 
signalled.</p></li><li><p><strong>if both are arrays</strong>:
+This resolution algorithm is applied recursively to the reader&rsquo;s and 
writer&rsquo;s array item schemas.</p></li><li><p><strong>if both are 
maps</strong>:
+This resolution algorithm is applied recursively to the reader&rsquo;s and 
writer&rsquo;s value schemas.</p></li><li><p><strong>if both are 
unions</strong>:
+The first schema in the reader&rsquo;s union that matches the selected 
writer&rsquo;s union schema is recursively resolved against it. if none match, 
an error is signalled.</p></li><li><p><strong>if reader&rsquo;s is a union, but 
writer&rsquo;s is not</strong>
+The first schema in the reader&rsquo;s union that matches the writer&rsquo;s 
schema is recursively resolved against it. If none match, an error is 
signalled.</p></li><li><p><strong>if writer&rsquo;s is a union, but 
reader&rsquo;s is not</strong>

[... 38 lines stripped ...]

Reply via email to