Deploying to gh-pages from @ GreptimeTeam/greptimedb@9a2ac7f9de 🚀

This commit is contained in:
github-merge-queue[bot]
2026-10-20 14:37:30 +00:00
commit a61d66e6f0
26072 changed files with 3030916 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/ast.rs`."><title>ast.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>ast.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">pub use </span>sqlparser::ast::{
<a href=#16 id=16 data-nosnippet>16</a> BinaryOperator, ColumnDef, ColumnOption, ColumnOptionDef, DataType, Expr, Function,
<a href=#17 id=17 data-nosnippet>17</a> FunctionArg, FunctionArgExpr, FunctionArguments, Ident, ObjectName, ObjectNamePart, SqlOption,
<a href=#18 id=18 data-nosnippet>18</a> TableConstraint, TimezoneInfo, Value, ValueWithSpan, Visit, VisitMut, Visitor, VisitorMut,
<a href=#19 id=19 data-nosnippet>19</a> visit_expressions_mut, visit_statements_mut,
<a href=#20 id=20 data-nosnippet>20</a>};
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">pub trait </span>ObjectNamePartExt {
<a href=#23 id=23 data-nosnippet>23</a> <span class="kw">fn </span>to_string_unquoted(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; String;
<a href=#24 id=24 data-nosnippet>24</a>}
<a href=#25 id=25 data-nosnippet>25</a>
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">impl </span>ObjectNamePartExt <span class="kw">for </span>ObjectNamePart {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">fn </span>to_string_unquoted(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; String {
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">let </span>ObjectNamePart::Identifier(ident) = <span class="self">self </span><span class="kw">else </span>{
<a href=#29 id=29 data-nosnippet>29</a> <span class="comment">// If it's not an ident, just return it as a string.
<a href=#30 id=30 data-nosnippet>30</a> </span><span class="kw">return </span><span class="self">self</span>.to_string();
<a href=#31 id=31 data-nosnippet>31</a> };
<a href=#32 id=32 data-nosnippet>32</a> ident.value.clone()
<a href=#33 id=33 data-nosnippet>33</a> }
<a href=#34 id=34 data-nosnippet>34</a>}
<a href=#35 id=35 data-nosnippet>35</a>
<a href=#36 id=36 data-nosnippet>36</a><span class="doccomment">/// Formats an object name by joining its identifier values without quotes.
<a href=#37 id=37 data-nosnippet>37</a></span><span class="kw">pub fn </span>object_name_to_string_unquoted(name: <span class="kw-2">&amp;</span>ObjectName) -&gt; String {
<a href=#38 id=38 data-nosnippet>38</a> name.<span class="number">0
<a href=#39 id=39 data-nosnippet>39</a> </span>.iter()
<a href=#40 id=40 data-nosnippet>40</a> .map(ObjectNamePartExt::to_string_unquoted)
<a href=#41 id=41 data-nosnippet>41</a> .collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;()
<a href=#42 id=42 data-nosnippet>42</a> .join(<span class="string">"."</span>)
<a href=#43 id=43 data-nosnippet>43</a>}
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a><span class="attr">#[cfg(test)]
<a href=#46 id=46 data-nosnippet>46</a></span><span class="kw">mod </span>tests {
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">use </span>sqlparser::ast::{Ident, ObjectName, ObjectNamePart};
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">use </span><span class="kw">super</span>::object_name_to_string_unquoted;
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a> <span class="attr">#[test]
<a href=#52 id=52 data-nosnippet>52</a> </span><span class="kw">fn </span>test_object_name_to_string_unquoted() {
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">let </span>quoted = ObjectName(<span class="macro">vec!</span>[ObjectNamePart::Identifier(Ident::with_quote(
<a href=#54 id=54 data-nosnippet>54</a> <span class="string">'"'</span>,
<a href=#55 id=55 data-nosnippet>55</a> <span class="string">"query.parallelism"</span>,
<a href=#56 id=56 data-nosnippet>56</a> ))]);
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">let </span>unquoted = ObjectName(<span class="macro">vec!</span>[
<a href=#58 id=58 data-nosnippet>58</a> ObjectNamePart::Identifier(Ident::new(<span class="string">"query"</span>)),
<a href=#59 id=59 data-nosnippet>59</a> ObjectNamePart::Identifier(Ident::new(<span class="string">"parallelism"</span>)),
<a href=#60 id=60 data-nosnippet>60</a> ]);
<a href=#61 id=61 data-nosnippet>61</a>
<a href=#62 id=62 data-nosnippet>62</a> <span class="macro">assert_eq!</span>(<span class="string">"query.parallelism"</span>, object_name_to_string_unquoted(<span class="kw-2">&amp;</span>quoted));
<a href=#63 id=63 data-nosnippet>63</a> <span class="macro">assert_eq!</span>(
<a href=#64 id=64 data-nosnippet>64</a> object_name_to_string_unquoted(<span class="kw-2">&amp;</span>unquoted),
<a href=#65 id=65 data-nosnippet>65</a> object_name_to_string_unquoted(<span class="kw-2">&amp;</span>quoted)
<a href=#66 id=66 data-nosnippet>66</a> );
<a href=#67 id=67 data-nosnippet>67</a> }
<a href=#68 id=68 data-nosnippet>68</a>}
</code></pre></div></section></main></body></html>
+48
View File
@@ -0,0 +1,48 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/dialect.rs`."><title>dialect.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>dialect.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">pub use </span>sqlparser::dialect::{Dialect, GenericDialect, MySqlDialect, PostgreSqlDialect};
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="doccomment">/// GreptimeDb dialect
<a href=#18 id=18 data-nosnippet>18</a></span><span class="attr">#[derive(Debug, Clone)]
<a href=#19 id=19 data-nosnippet>19</a></span><span class="kw">pub struct </span>GreptimeDbDialect {}
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">impl </span>Dialect <span class="kw">for </span>GreptimeDbDialect {
<a href=#22 id=22 data-nosnippet>22</a> <span class="kw">fn </span>is_identifier_start(<span class="kw-2">&amp;</span><span class="self">self</span>, ch: char) -&gt; bool {
<a href=#23 id=23 data-nosnippet>23</a> ch.is_alphabetic() || ch == <span class="string">'_' </span>|| ch == <span class="string">'#' </span>|| ch == <span class="string">'@'
<a href=#24 id=24 data-nosnippet>24</a> </span>}
<a href=#25 id=25 data-nosnippet>25</a>
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">fn </span>is_identifier_part(<span class="kw-2">&amp;</span><span class="self">self</span>, ch: char) -&gt; bool {
<a href=#27 id=27 data-nosnippet>27</a> ch.is_alphabetic()
<a href=#28 id=28 data-nosnippet>28</a> || ch.is_ascii_digit()
<a href=#29 id=29 data-nosnippet>29</a> || ch == <span class="string">'@'
<a href=#30 id=30 data-nosnippet>30</a> </span>|| ch == <span class="string">'$'
<a href=#31 id=31 data-nosnippet>31</a> </span>|| ch == <span class="string">'#'
<a href=#32 id=32 data-nosnippet>32</a> </span>|| ch == <span class="string">'_'
<a href=#33 id=33 data-nosnippet>33</a> </span>}
<a href=#34 id=34 data-nosnippet>34</a>
<a href=#35 id=35 data-nosnippet>35</a> <span class="comment">// Accepts both `identifier` and "identifier".
<a href=#36 id=36 data-nosnippet>36</a> </span><span class="kw">fn </span>is_delimited_identifier_start(<span class="kw-2">&amp;</span><span class="self">self</span>, ch: char) -&gt; bool {
<a href=#37 id=37 data-nosnippet>37</a> ch == <span class="string">'`' </span>|| ch == <span class="string">'"'
<a href=#38 id=38 data-nosnippet>38</a> </span>}
<a href=#39 id=39 data-nosnippet>39</a>
<a href=#40 id=40 data-nosnippet>40</a> <span class="kw">fn </span>supports_filter_during_aggregation(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#41 id=41 data-nosnippet>41</a> <span class="bool-val">true
<a href=#42 id=42 data-nosnippet>42</a> </span>}
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a> <span class="kw">fn </span>supports_struct_literal(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#45 id=45 data-nosnippet>45</a> <span class="bool-val">true
<a href=#46 id=46 data-nosnippet>46</a> </span>}
<a href=#47 id=47 data-nosnippet>47</a>}
</code></pre></div></section></main></body></html>
+423
View File
@@ -0,0 +1,423 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/error.rs`."><title>error.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>error.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::any::Any;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>common_error::ext::ErrorExt;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>common_error::status_code::StatusCode;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>common_macro::stack_trace_debug;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>datafusion_common::DataFusionError;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>datatypes::prelude::{ConcreteDataType, Value};
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>snafu::{Location, Snafu};
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>sqlparser::parser::ParserError;
<a href=#24 id=24 data-nosnippet>24</a>
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::parsers::error::TQLError;
<a href=#26 id=26 data-nosnippet>26</a>
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">pub type </span><span class="prelude-ty">Result</span>&lt;T&gt; = std::result::Result&lt;T, Error&gt;;
<a href=#28 id=28 data-nosnippet>28</a>
<a href=#29 id=29 data-nosnippet>29</a><span class="doccomment">/// SQL parser errors.
<a href=#30 id=30 data-nosnippet>30</a></span><span class="comment">// Now the error in parser does not contain backtrace to avoid generating backtrace
<a href=#31 id=31 data-nosnippet>31</a>// every time the parser parses an invalid SQL.
<a href=#32 id=32 data-nosnippet>32</a></span><span class="attr">#[derive(Snafu)]
<a href=#33 id=33 data-nosnippet>33</a>#[snafu(visibility(<span class="kw">pub</span>))]
<a href=#34 id=34 data-nosnippet>34</a>#[stack_trace_debug]
<a href=#35 id=35 data-nosnippet>35</a></span><span class="kw">pub enum </span>Error {
<a href=#36 id=36 data-nosnippet>36</a> <span class="attr">#[snafu(display(<span class="string">"SQL statement is not supported, keyword: {}"</span>, keyword))]
<a href=#37 id=37 data-nosnippet>37</a> </span>Unsupported {
<a href=#38 id=38 data-nosnippet>38</a> keyword: String,
<a href=#39 id=39 data-nosnippet>39</a> <span class="attr">#[snafu(implicit)]
<a href=#40 id=40 data-nosnippet>40</a> </span>location: Location,
<a href=#41 id=41 data-nosnippet>41</a> },
<a href=#42 id=42 data-nosnippet>42</a>
<a href=#43 id=43 data-nosnippet>43</a> <span class="attr">#[snafu(display(
<a href=#44 id=44 data-nosnippet>44</a> <span class="string">"Unexpected token while parsing SQL statement, expected: '{}', found: {}"</span>,
<a href=#45 id=45 data-nosnippet>45</a> expected,
<a href=#46 id=46 data-nosnippet>46</a> actual,
<a href=#47 id=47 data-nosnippet>47</a> ))]
<a href=#48 id=48 data-nosnippet>48</a> </span>Unexpected {
<a href=#49 id=49 data-nosnippet>49</a> expected: String,
<a href=#50 id=50 data-nosnippet>50</a> actual: String,
<a href=#51 id=51 data-nosnippet>51</a> <span class="attr">#[snafu(source)]
<a href=#52 id=52 data-nosnippet>52</a> </span>error: ParserError,
<a href=#53 id=53 data-nosnippet>53</a> <span class="attr">#[snafu(implicit)]
<a href=#54 id=54 data-nosnippet>54</a> </span>location: Location,
<a href=#55 id=55 data-nosnippet>55</a> },
<a href=#56 id=56 data-nosnippet>56</a>
<a href=#57 id=57 data-nosnippet>57</a> <span class="comment">// Syntax error from sql parser.
<a href=#58 id=58 data-nosnippet>58</a> </span><span class="attr">#[snafu(display(<span class="string">"Invalid SQL syntax"</span>))]
<a href=#59 id=59 data-nosnippet>59</a> </span>Syntax {
<a href=#60 id=60 data-nosnippet>60</a> <span class="attr">#[snafu(source)]
<a href=#61 id=61 data-nosnippet>61</a> </span>error: ParserError,
<a href=#62 id=62 data-nosnippet>62</a> <span class="attr">#[snafu(implicit)]
<a href=#63 id=63 data-nosnippet>63</a> </span>location: Location,
<a href=#64 id=64 data-nosnippet>64</a> },
<a href=#65 id=65 data-nosnippet>65</a>
<a href=#66 id=66 data-nosnippet>66</a> <span class="comment">// Syntax error from tql parser.
<a href=#67 id=67 data-nosnippet>67</a> </span><span class="attr">#[snafu(display(<span class="string">"Invalid TQL syntax"</span>))]
<a href=#68 id=68 data-nosnippet>68</a> </span>TQLSyntax {
<a href=#69 id=69 data-nosnippet>69</a> <span class="attr">#[snafu(source)]
<a href=#70 id=70 data-nosnippet>70</a> </span>error: TQLError,
<a href=#71 id=71 data-nosnippet>71</a> <span class="attr">#[snafu(implicit)]
<a href=#72 id=72 data-nosnippet>72</a> </span>location: Location,
<a href=#73 id=73 data-nosnippet>73</a> },
<a href=#74 id=74 data-nosnippet>74</a>
<a href=#75 id=75 data-nosnippet>75</a> <span class="attr">#[snafu(display(<span class="string">"Missing time index constraint"</span>))]
<a href=#76 id=76 data-nosnippet>76</a> </span>MissingTimeIndex {},
<a href=#77 id=77 data-nosnippet>77</a>
<a href=#78 id=78 data-nosnippet>78</a> <span class="attr">#[snafu(display(<span class="string">"Invalid time index: {}"</span>, msg))]
<a href=#79 id=79 data-nosnippet>79</a> </span>InvalidTimeIndex {
<a href=#80 id=80 data-nosnippet>80</a> msg: String,
<a href=#81 id=81 data-nosnippet>81</a> <span class="attr">#[snafu(implicit)]
<a href=#82 id=82 data-nosnippet>82</a> </span>location: Location,
<a href=#83 id=83 data-nosnippet>83</a> },
<a href=#84 id=84 data-nosnippet>84</a>
<a href=#85 id=85 data-nosnippet>85</a> <span class="attr">#[snafu(display(<span class="string">"Invalid SQL, error: {}"</span>, msg))]
<a href=#86 id=86 data-nosnippet>86</a> </span>InvalidSql {
<a href=#87 id=87 data-nosnippet>87</a> msg: String,
<a href=#88 id=88 data-nosnippet>88</a> <span class="attr">#[snafu(implicit)]
<a href=#89 id=89 data-nosnippet>89</a> </span>location: Location,
<a href=#90 id=90 data-nosnippet>90</a> },
<a href=#91 id=91 data-nosnippet>91</a>
<a href=#92 id=92 data-nosnippet>92</a> <span class="attr">#[snafu(display(
<a href=#93 id=93 data-nosnippet>93</a> <span class="string">"Unexpected token while parsing SQL statement, expected: '{}', found: {}"</span>,
<a href=#94 id=94 data-nosnippet>94</a> expected,
<a href=#95 id=95 data-nosnippet>95</a> actual,
<a href=#96 id=96 data-nosnippet>96</a> ))]
<a href=#97 id=97 data-nosnippet>97</a> </span>UnexpectedToken {
<a href=#98 id=98 data-nosnippet>98</a> expected: String,
<a href=#99 id=99 data-nosnippet>99</a> actual: String,
<a href=#100 id=100 data-nosnippet>100</a> <span class="attr">#[snafu(implicit)]
<a href=#101 id=101 data-nosnippet>101</a> </span>location: Location,
<a href=#102 id=102 data-nosnippet>102</a> },
<a href=#103 id=103 data-nosnippet>103</a>
<a href=#104 id=104 data-nosnippet>104</a> <span class="attr">#[snafu(display(<span class="string">"Invalid column option, column name: {}, error: {}"</span>, name, msg))]
<a href=#105 id=105 data-nosnippet>105</a> </span>InvalidColumnOption {
<a href=#106 id=106 data-nosnippet>106</a> name: String,
<a href=#107 id=107 data-nosnippet>107</a> msg: String,
<a href=#108 id=108 data-nosnippet>108</a> <span class="attr">#[snafu(implicit)]
<a href=#109 id=109 data-nosnippet>109</a> </span>location: Location,
<a href=#110 id=110 data-nosnippet>110</a> },
<a href=#111 id=111 data-nosnippet>111</a>
<a href=#112 id=112 data-nosnippet>112</a> <span class="attr">#[snafu(display(<span class="string">"SQL data type not supported yet: {:?}"</span>, t))]
<a href=#113 id=113 data-nosnippet>113</a> </span>SqlTypeNotSupported {
<a href=#114 id=114 data-nosnippet>114</a> t: <span class="kw">crate</span>::ast::DataType,
<a href=#115 id=115 data-nosnippet>115</a> <span class="attr">#[snafu(implicit)]
<a href=#116 id=116 data-nosnippet>116</a> </span>location: Location,
<a href=#117 id=117 data-nosnippet>117</a> },
<a href=#118 id=118 data-nosnippet>118</a> <span class="attr">#[snafu(display(<span class="string">"ConcreteDataType not supported yet: {:?}"</span>, t))]
<a href=#119 id=119 data-nosnippet>119</a> </span>ConcreteTypeNotSupported {
<a href=#120 id=120 data-nosnippet>120</a> t: ConcreteDataType,
<a href=#121 id=121 data-nosnippet>121</a> <span class="attr">#[snafu(implicit)]
<a href=#122 id=122 data-nosnippet>122</a> </span>location: Location,
<a href=#123 id=123 data-nosnippet>123</a> },
<a href=#124 id=124 data-nosnippet>124</a>
<a href=#125 id=125 data-nosnippet>125</a> <span class="attr">#[snafu(display(<span class="string">"Failed to parse value: {}"</span>, msg))]
<a href=#126 id=126 data-nosnippet>126</a> </span>ParseSqlValue {
<a href=#127 id=127 data-nosnippet>127</a> msg: String,
<a href=#128 id=128 data-nosnippet>128</a> <span class="attr">#[snafu(implicit)]
<a href=#129 id=129 data-nosnippet>129</a> </span>location: Location,
<a href=#130 id=130 data-nosnippet>130</a> },
<a href=#131 id=131 data-nosnippet>131</a>
<a href=#132 id=132 data-nosnippet>132</a> <span class="attr">#[snafu(display(
<a href=#133 id=133 data-nosnippet>133</a> <span class="string">"Column {} expect type: {:?}, actual: {:?}"</span>,
<a href=#134 id=134 data-nosnippet>134</a> column_name,
<a href=#135 id=135 data-nosnippet>135</a> expect,
<a href=#136 id=136 data-nosnippet>136</a> actual,
<a href=#137 id=137 data-nosnippet>137</a> ))]
<a href=#138 id=138 data-nosnippet>138</a> </span>ColumnTypeMismatch {
<a href=#139 id=139 data-nosnippet>139</a> column_name: String,
<a href=#140 id=140 data-nosnippet>140</a> expect: ConcreteDataType,
<a href=#141 id=141 data-nosnippet>141</a> actual: ConcreteDataType,
<a href=#142 id=142 data-nosnippet>142</a> <span class="attr">#[snafu(implicit)]
<a href=#143 id=143 data-nosnippet>143</a> </span>location: Location,
<a href=#144 id=144 data-nosnippet>144</a> },
<a href=#145 id=145 data-nosnippet>145</a>
<a href=#146 id=146 data-nosnippet>146</a> <span class="attr">#[snafu(display(<span class="string">"Invalid database name: {}"</span>, name))]
<a href=#147 id=147 data-nosnippet>147</a> </span>InvalidDatabaseName {
<a href=#148 id=148 data-nosnippet>148</a> name: String,
<a href=#149 id=149 data-nosnippet>149</a> <span class="attr">#[snafu(implicit)]
<a href=#150 id=150 data-nosnippet>150</a> </span>location: Location,
<a href=#151 id=151 data-nosnippet>151</a> },
<a href=#152 id=152 data-nosnippet>152</a>
<a href=#153 id=153 data-nosnippet>153</a> <span class="attr">#[snafu(display(<span class="string">"Invalid interval provided: {}"</span>, reason))]
<a href=#154 id=154 data-nosnippet>154</a> </span>InvalidInterval {
<a href=#155 id=155 data-nosnippet>155</a> reason: String,
<a href=#156 id=156 data-nosnippet>156</a> <span class="attr">#[snafu(implicit)]
<a href=#157 id=157 data-nosnippet>157</a> </span>location: Location,
<a href=#158 id=158 data-nosnippet>158</a> },
<a href=#159 id=159 data-nosnippet>159</a>
<a href=#160 id=160 data-nosnippet>160</a> <span class="attr">#[snafu(display(<span class="string">"Unrecognized database option key: {}"</span>, key))]
<a href=#161 id=161 data-nosnippet>161</a> </span>InvalidDatabaseOption {
<a href=#162 id=162 data-nosnippet>162</a> key: String,
<a href=#163 id=163 data-nosnippet>163</a> <span class="attr">#[snafu(implicit)]
<a href=#164 id=164 data-nosnippet>164</a> </span>location: Location,
<a href=#165 id=165 data-nosnippet>165</a> },
<a href=#166 id=166 data-nosnippet>166</a>
<a href=#167 id=167 data-nosnippet>167</a> <span class="attr">#[snafu(display(<span class="string">"Invalid database option value for {}: {}, {}"</span>, key, value, reason))]
<a href=#168 id=168 data-nosnippet>168</a> </span>InvalidDatabaseOptionValue {
<a href=#169 id=169 data-nosnippet>169</a> key: String,
<a href=#170 id=170 data-nosnippet>170</a> value: String,
<a href=#171 id=171 data-nosnippet>171</a> reason: String,
<a href=#172 id=172 data-nosnippet>172</a> <span class="attr">#[snafu(implicit)]
<a href=#173 id=173 data-nosnippet>173</a> </span>location: Location,
<a href=#174 id=174 data-nosnippet>174</a> },
<a href=#175 id=175 data-nosnippet>175</a>
<a href=#176 id=176 data-nosnippet>176</a> <span class="attr">#[snafu(display(<span class="string">"Invalid table name: {}"</span>, name))]
<a href=#177 id=177 data-nosnippet>177</a> </span>InvalidTableName {
<a href=#178 id=178 data-nosnippet>178</a> name: String,
<a href=#179 id=179 data-nosnippet>179</a> <span class="attr">#[snafu(implicit)]
<a href=#180 id=180 data-nosnippet>180</a> </span>location: Location,
<a href=#181 id=181 data-nosnippet>181</a> },
<a href=#182 id=182 data-nosnippet>182</a>
<a href=#183 id=183 data-nosnippet>183</a> <span class="attr">#[snafu(display(<span class="string">"Invalid flow name: {}"</span>, name))]
<a href=#184 id=184 data-nosnippet>184</a> </span>InvalidFlowName {
<a href=#185 id=185 data-nosnippet>185</a> name: String,
<a href=#186 id=186 data-nosnippet>186</a> <span class="attr">#[snafu(implicit)]
<a href=#187 id=187 data-nosnippet>187</a> </span>location: Location,
<a href=#188 id=188 data-nosnippet>188</a> },
<a href=#189 id=189 data-nosnippet>189</a>
<a href=#190 id=190 data-nosnippet>190</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#191 id=191 data-nosnippet>191</a> #[snafu(display(<span class="string">"Invalid trigger name: {}"</span>, name))]
<a href=#192 id=192 data-nosnippet>192</a> </span>InvalidTriggerName {
<a href=#193 id=193 data-nosnippet>193</a> name: String,
<a href=#194 id=194 data-nosnippet>194</a> <span class="attr">#[snafu(implicit)]
<a href=#195 id=195 data-nosnippet>195</a> </span>location: Location,
<a href=#196 id=196 data-nosnippet>196</a> },
<a href=#197 id=197 data-nosnippet>197</a>
<a href=#198 id=198 data-nosnippet>198</a> <span class="attr">#[snafu(display(<span class="string">"Invalid flow query: {}"</span>, reason))]
<a href=#199 id=199 data-nosnippet>199</a> </span>InvalidFlowQuery {
<a href=#200 id=200 data-nosnippet>200</a> reason: String,
<a href=#201 id=201 data-nosnippet>201</a> <span class="attr">#[snafu(implicit)]
<a href=#202 id=202 data-nosnippet>202</a> </span>location: Location,
<a href=#203 id=203 data-nosnippet>203</a> },
<a href=#204 id=204 data-nosnippet>204</a>
<a href=#205 id=205 data-nosnippet>205</a> <span class="attr">#[snafu(display(<span class="string">"Invalid default constraint, column: {}"</span>, column))]
<a href=#206 id=206 data-nosnippet>206</a> </span>InvalidDefault {
<a href=#207 id=207 data-nosnippet>207</a> column: String,
<a href=#208 id=208 data-nosnippet>208</a> <span class="attr">#[snafu(implicit)]
<a href=#209 id=209 data-nosnippet>209</a> </span>location: Location,
<a href=#210 id=210 data-nosnippet>210</a> source: datatypes::error::Error,
<a href=#211 id=211 data-nosnippet>211</a> },
<a href=#212 id=212 data-nosnippet>212</a>
<a href=#213 id=213 data-nosnippet>213</a> <span class="attr">#[snafu(display(<span class="string">"Unrecognized table option key: {}"</span>, key))]
<a href=#214 id=214 data-nosnippet>214</a> </span>InvalidTableOption {
<a href=#215 id=215 data-nosnippet>215</a> key: String,
<a href=#216 id=216 data-nosnippet>216</a> <span class="attr">#[snafu(implicit)]
<a href=#217 id=217 data-nosnippet>217</a> </span>location: Location,
<a href=#218 id=218 data-nosnippet>218</a> },
<a href=#219 id=219 data-nosnippet>219</a>
<a href=#220 id=220 data-nosnippet>220</a> <span class="attr">#[snafu(display(<span class="string">"Invalid expr as option value, error: {error}"</span>))]
<a href=#221 id=221 data-nosnippet>221</a> </span>InvalidExprAsOptionValue {
<a href=#222 id=222 data-nosnippet>222</a> error: String,
<a href=#223 id=223 data-nosnippet>223</a> <span class="attr">#[snafu(implicit)]
<a href=#224 id=224 data-nosnippet>224</a> </span>location: Location,
<a href=#225 id=225 data-nosnippet>225</a> },
<a href=#226 id=226 data-nosnippet>226</a>
<a href=#227 id=227 data-nosnippet>227</a> <span class="attr">#[snafu(display(<span class="string">"Failed to serialize column default constraint"</span>))]
<a href=#228 id=228 data-nosnippet>228</a> </span>SerializeColumnDefaultConstraint {
<a href=#229 id=229 data-nosnippet>229</a> <span class="attr">#[snafu(implicit)]
<a href=#230 id=230 data-nosnippet>230</a> </span>location: Location,
<a href=#231 id=231 data-nosnippet>231</a> source: datatypes::error::Error,
<a href=#232 id=232 data-nosnippet>232</a> },
<a href=#233 id=233 data-nosnippet>233</a>
<a href=#234 id=234 data-nosnippet>234</a> <span class="attr">#[snafu(display(<span class="string">"Failed to convert data type to gRPC data type defined in proto"</span>))]
<a href=#235 id=235 data-nosnippet>235</a> </span>ConvertToGrpcDataType {
<a href=#236 id=236 data-nosnippet>236</a> <span class="attr">#[snafu(implicit)]
<a href=#237 id=237 data-nosnippet>237</a> </span>location: Location,
<a href=#238 id=238 data-nosnippet>238</a> source: api::error::Error,
<a href=#239 id=239 data-nosnippet>239</a> },
<a href=#240 id=240 data-nosnippet>240</a>
<a href=#241 id=241 data-nosnippet>241</a> <span class="attr">#[snafu(display(<span class="string">"Unable to convert statement {} to DataFusion statement"</span>, statement))]
<a href=#242 id=242 data-nosnippet>242</a> </span>ConvertToDfStatement {
<a href=#243 id=243 data-nosnippet>243</a> statement: String,
<a href=#244 id=244 data-nosnippet>244</a> <span class="attr">#[snafu(implicit)]
<a href=#245 id=245 data-nosnippet>245</a> </span>location: Location,
<a href=#246 id=246 data-nosnippet>246</a> },
<a href=#247 id=247 data-nosnippet>247</a>
<a href=#248 id=248 data-nosnippet>248</a> <span class="attr">#[snafu(display(<span class="string">"Unable to convert value {} to sql value"</span>, value))]
<a href=#249 id=249 data-nosnippet>249</a> </span>ConvertValue {
<a href=#250 id=250 data-nosnippet>250</a> value: Value,
<a href=#251 id=251 data-nosnippet>251</a> <span class="attr">#[snafu(implicit)]
<a href=#252 id=252 data-nosnippet>252</a> </span>location: Location,
<a href=#253 id=253 data-nosnippet>253</a> },
<a href=#254 id=254 data-nosnippet>254</a>
<a href=#255 id=255 data-nosnippet>255</a> <span class="attr">#[snafu(display(<span class="string">"Failed to convert to logical TQL expression"</span>))]
<a href=#256 id=256 data-nosnippet>256</a> </span>ConvertToLogicalExpression {
<a href=#257 id=257 data-nosnippet>257</a> <span class="attr">#[snafu(source)]
<a href=#258 id=258 data-nosnippet>258</a> </span>error: DataFusionError,
<a href=#259 id=259 data-nosnippet>259</a> <span class="attr">#[snafu(implicit)]
<a href=#260 id=260 data-nosnippet>260</a> </span>location: Location,
<a href=#261 id=261 data-nosnippet>261</a> },
<a href=#262 id=262 data-nosnippet>262</a>
<a href=#263 id=263 data-nosnippet>263</a> <span class="attr">#[snafu(display(<span class="string">"Failed to simplify TQL expression"</span>))]
<a href=#264 id=264 data-nosnippet>264</a> </span>Simplification {
<a href=#265 id=265 data-nosnippet>265</a> <span class="attr">#[snafu(source)]
<a href=#266 id=266 data-nosnippet>266</a> </span>error: DataFusionError,
<a href=#267 id=267 data-nosnippet>267</a> <span class="attr">#[snafu(implicit)]
<a href=#268 id=268 data-nosnippet>268</a> </span>location: Location,
<a href=#269 id=269 data-nosnippet>269</a> },
<a href=#270 id=270 data-nosnippet>270</a>
<a href=#271 id=271 data-nosnippet>271</a> <span class="attr">#[snafu(display(
<a href=#272 id=272 data-nosnippet>272</a> <span class="string">"Permission denied while operating catalog {} from current catalog {}"</span>,
<a href=#273 id=273 data-nosnippet>273</a> target,
<a href=#274 id=274 data-nosnippet>274</a> current
<a href=#275 id=275 data-nosnippet>275</a> ))]
<a href=#276 id=276 data-nosnippet>276</a> </span>PermissionDenied {
<a href=#277 id=277 data-nosnippet>277</a> target: String,
<a href=#278 id=278 data-nosnippet>278</a> current: String,
<a href=#279 id=279 data-nosnippet>279</a> <span class="attr">#[snafu(implicit)]
<a href=#280 id=280 data-nosnippet>280</a> </span>location: Location,
<a href=#281 id=281 data-nosnippet>281</a> },
<a href=#282 id=282 data-nosnippet>282</a>
<a href=#283 id=283 data-nosnippet>283</a> <span class="attr">#[snafu(display(<span class="string">"Failed to set fulltext option"</span>))]
<a href=#284 id=284 data-nosnippet>284</a> </span>SetFulltextOption {
<a href=#285 id=285 data-nosnippet>285</a> source: datatypes::error::Error,
<a href=#286 id=286 data-nosnippet>286</a> <span class="attr">#[snafu(implicit)]
<a href=#287 id=287 data-nosnippet>287</a> </span>location: Location,
<a href=#288 id=288 data-nosnippet>288</a> },
<a href=#289 id=289 data-nosnippet>289</a>
<a href=#290 id=290 data-nosnippet>290</a> <span class="attr">#[snafu(display(<span class="string">"Failed to set SKIPPING index option"</span>))]
<a href=#291 id=291 data-nosnippet>291</a> </span>SetSkippingIndexOption {
<a href=#292 id=292 data-nosnippet>292</a> source: datatypes::error::Error,
<a href=#293 id=293 data-nosnippet>293</a> <span class="attr">#[snafu(implicit)]
<a href=#294 id=294 data-nosnippet>294</a> </span>location: Location,
<a href=#295 id=295 data-nosnippet>295</a> },
<a href=#296 id=296 data-nosnippet>296</a>
<a href=#297 id=297 data-nosnippet>297</a> <span class="attr">#[snafu(display(<span class="string">"Failed to set COMPRESSION option"</span>))]
<a href=#298 id=298 data-nosnippet>298</a> </span>SetCompressionOption {
<a href=#299 id=299 data-nosnippet>299</a> source: datatypes::error::Error,
<a href=#300 id=300 data-nosnippet>300</a> <span class="attr">#[snafu(implicit)]
<a href=#301 id=301 data-nosnippet>301</a> </span>location: Location,
<a href=#302 id=302 data-nosnippet>302</a> },
<a href=#303 id=303 data-nosnippet>303</a>
<a href=#304 id=304 data-nosnippet>304</a> <span class="attr">#[snafu(display(
<a href=#305 id=305 data-nosnippet>305</a> <span class="string">"Invalid partition number: {}, should be in range [2, 65536]"</span>,
<a href=#306 id=306 data-nosnippet>306</a> partition_num
<a href=#307 id=307 data-nosnippet>307</a> ))]
<a href=#308 id=308 data-nosnippet>308</a> </span>InvalidPartitionNumber {
<a href=#309 id=309 data-nosnippet>309</a> partition_num: u32,
<a href=#310 id=310 data-nosnippet>310</a> <span class="attr">#[snafu(implicit)]
<a href=#311 id=311 data-nosnippet>311</a> </span>location: Location,
<a href=#312 id=312 data-nosnippet>312</a> },
<a href=#313 id=313 data-nosnippet>313</a>
<a href=#314 id=314 data-nosnippet>314</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#315 id=315 data-nosnippet>315</a> #[snafu(display(<span class="string">"Missing `{}` clause"</span>, name))]
<a href=#316 id=316 data-nosnippet>316</a> </span>MissingClause {
<a href=#317 id=317 data-nosnippet>317</a> name: String,
<a href=#318 id=318 data-nosnippet>318</a> <span class="attr">#[snafu(implicit)]
<a href=#319 id=319 data-nosnippet>319</a> </span>location: Location,
<a href=#320 id=320 data-nosnippet>320</a> },
<a href=#321 id=321 data-nosnippet>321</a>
<a href=#322 id=322 data-nosnippet>322</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#323 id=323 data-nosnippet>323</a> #[snafu(display(<span class="string">"Unrecognized trigger webhook option key: {}"</span>, key))]
<a href=#324 id=324 data-nosnippet>324</a> </span>InvalidTriggerWebhookOption {
<a href=#325 id=325 data-nosnippet>325</a> key: String,
<a href=#326 id=326 data-nosnippet>326</a> <span class="attr">#[snafu(implicit)]
<a href=#327 id=327 data-nosnippet>327</a> </span>location: Location,
<a href=#328 id=328 data-nosnippet>328</a> },
<a href=#329 id=329 data-nosnippet>329</a>
<a href=#330 id=330 data-nosnippet>330</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#331 id=331 data-nosnippet>331</a> #[snafu(display(<span class="string">"Must specify at least one notify channel"</span>))]
<a href=#332 id=332 data-nosnippet>332</a> </span>MissingNotifyChannel {
<a href=#333 id=333 data-nosnippet>333</a> <span class="attr">#[snafu(implicit)]
<a href=#334 id=334 data-nosnippet>334</a> </span>location: Location,
<a href=#335 id=335 data-nosnippet>335</a> },
<a href=#336 id=336 data-nosnippet>336</a>
<a href=#337 id=337 data-nosnippet>337</a> <span class="attr">#[snafu(display(<span class="string">"Sql common error"</span>))]
<a href=#338 id=338 data-nosnippet>338</a> </span>SqlCommon {
<a href=#339 id=339 data-nosnippet>339</a> source: common_sql::error::Error,
<a href=#340 id=340 data-nosnippet>340</a> <span class="attr">#[snafu(implicit)]
<a href=#341 id=341 data-nosnippet>341</a> </span>location: Location,
<a href=#342 id=342 data-nosnippet>342</a> },
<a href=#343 id=343 data-nosnippet>343</a>
<a href=#344 id=344 data-nosnippet>344</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#345 id=345 data-nosnippet>345</a> #[snafu(display(<span class="string">"Duplicate clauses `{}` in a statement"</span>, clause))]
<a href=#346 id=346 data-nosnippet>346</a> </span>DuplicateClause {
<a href=#347 id=347 data-nosnippet>347</a> clause: String,
<a href=#348 id=348 data-nosnippet>348</a> <span class="attr">#[snafu(implicit)]
<a href=#349 id=349 data-nosnippet>349</a> </span>location: Location,
<a href=#350 id=350 data-nosnippet>350</a> },
<a href=#351 id=351 data-nosnippet>351</a>
<a href=#352 id=352 data-nosnippet>352</a> <span class="attr">#[snafu(transparent)]
<a href=#353 id=353 data-nosnippet>353</a> </span>Datatypes {
<a href=#354 id=354 data-nosnippet>354</a> <span class="attr">#[snafu(implicit)]
<a href=#355 id=355 data-nosnippet>355</a> </span>location: Location,
<a href=#356 id=356 data-nosnippet>356</a> source: datatypes::error::Error,
<a href=#357 id=357 data-nosnippet>357</a> },
<a href=#358 id=358 data-nosnippet>358</a>}
<a href=#359 id=359 data-nosnippet>359</a>
<a href=#360 id=360 data-nosnippet>360</a><span class="kw">impl </span>ErrorExt <span class="kw">for </span>Error {
<a href=#361 id=361 data-nosnippet>361</a> <span class="kw">fn </span>status_code(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; StatusCode {
<a href=#362 id=362 data-nosnippet>362</a> <span class="kw">use </span>Error::<span class="kw-2">*</span>;
<a href=#363 id=363 data-nosnippet>363</a>
<a href=#364 id=364 data-nosnippet>364</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#365 id=365 data-nosnippet>365</a> Unsupported { .. } =&gt; StatusCode::Unsupported,
<a href=#366 id=366 data-nosnippet>366</a> Unexpected { .. }
<a href=#367 id=367 data-nosnippet>367</a> | Syntax { .. }
<a href=#368 id=368 data-nosnippet>368</a> | TQLSyntax { .. }
<a href=#369 id=369 data-nosnippet>369</a> | MissingTimeIndex { .. }
<a href=#370 id=370 data-nosnippet>370</a> | InvalidTimeIndex { .. }
<a href=#371 id=371 data-nosnippet>371</a> | InvalidSql { .. }
<a href=#372 id=372 data-nosnippet>372</a> | ParseSqlValue { .. }
<a href=#373 id=373 data-nosnippet>373</a> | SqlTypeNotSupported { .. }
<a href=#374 id=374 data-nosnippet>374</a> | ConcreteTypeNotSupported { .. }
<a href=#375 id=375 data-nosnippet>375</a> | UnexpectedToken { .. }
<a href=#376 id=376 data-nosnippet>376</a> | InvalidDefault { .. } =&gt; StatusCode::InvalidSyntax,
<a href=#377 id=377 data-nosnippet>377</a>
<a href=#378 id=378 data-nosnippet>378</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#379 id=379 data-nosnippet>379</a> </span>MissingClause { .. } | MissingNotifyChannel { .. } | DuplicateClause { .. } =&gt; {
<a href=#380 id=380 data-nosnippet>380</a> StatusCode::InvalidSyntax
<a href=#381 id=381 data-nosnippet>381</a> }
<a href=#382 id=382 data-nosnippet>382</a>
<a href=#383 id=383 data-nosnippet>383</a> InvalidColumnOption { .. }
<a href=#384 id=384 data-nosnippet>384</a> | InvalidExprAsOptionValue { .. }
<a href=#385 id=385 data-nosnippet>385</a> | InvalidDatabaseName { .. }
<a href=#386 id=386 data-nosnippet>386</a> | InvalidDatabaseOption { .. }
<a href=#387 id=387 data-nosnippet>387</a> | InvalidDatabaseOptionValue { .. }
<a href=#388 id=388 data-nosnippet>388</a> | ColumnTypeMismatch { .. }
<a href=#389 id=389 data-nosnippet>389</a> | InvalidTableName { .. }
<a href=#390 id=390 data-nosnippet>390</a> | InvalidFlowName { .. }
<a href=#391 id=391 data-nosnippet>391</a> | InvalidFlowQuery { .. }
<a href=#392 id=392 data-nosnippet>392</a> | InvalidTableOption { .. }
<a href=#393 id=393 data-nosnippet>393</a> | ConvertToLogicalExpression { .. }
<a href=#394 id=394 data-nosnippet>394</a> | Simplification { .. }
<a href=#395 id=395 data-nosnippet>395</a> | InvalidInterval { .. }
<a href=#396 id=396 data-nosnippet>396</a> | InvalidPartitionNumber { .. } =&gt; StatusCode::InvalidArguments,
<a href=#397 id=397 data-nosnippet>397</a>
<a href=#398 id=398 data-nosnippet>398</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#399 id=399 data-nosnippet>399</a> </span>InvalidTriggerName { .. } =&gt; StatusCode::InvalidArguments,
<a href=#400 id=400 data-nosnippet>400</a>
<a href=#401 id=401 data-nosnippet>401</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#402 id=402 data-nosnippet>402</a> </span>InvalidTriggerWebhookOption { .. } =&gt; StatusCode::InvalidArguments,
<a href=#403 id=403 data-nosnippet>403</a>
<a href=#404 id=404 data-nosnippet>404</a> SerializeColumnDefaultConstraint { source, .. } | Datatypes { source, .. } =&gt; {
<a href=#405 id=405 data-nosnippet>405</a> source.status_code()
<a href=#406 id=406 data-nosnippet>406</a> }
<a href=#407 id=407 data-nosnippet>407</a>
<a href=#408 id=408 data-nosnippet>408</a> ConvertToGrpcDataType { source, .. } =&gt; source.status_code(),
<a href=#409 id=409 data-nosnippet>409</a> SqlCommon { source, .. } =&gt; source.status_code(),
<a href=#410 id=410 data-nosnippet>410</a> ConvertToDfStatement { .. } =&gt; StatusCode::Internal,
<a href=#411 id=411 data-nosnippet>411</a> ConvertValue { .. } =&gt; StatusCode::Unsupported,
<a href=#412 id=412 data-nosnippet>412</a>
<a href=#413 id=413 data-nosnippet>413</a> PermissionDenied { .. } =&gt; StatusCode::PermissionDenied,
<a href=#414 id=414 data-nosnippet>414</a> SetFulltextOption { .. } | SetSkippingIndexOption { .. } =&gt; StatusCode::Unexpected,
<a href=#415 id=415 data-nosnippet>415</a> SetCompressionOption { source, .. } =&gt; source.status_code(),
<a href=#416 id=416 data-nosnippet>416</a> }
<a href=#417 id=417 data-nosnippet>417</a> }
<a href=#418 id=418 data-nosnippet>418</a>
<a href=#419 id=419 data-nosnippet>419</a> <span class="kw">fn </span>as_any(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="kw">dyn </span>Any {
<a href=#420 id=420 data-nosnippet>420</a> <span class="self">self
<a href=#421 id=421 data-nosnippet>421</a> </span>}
<a href=#422 id=422 data-nosnippet>422</a>}
</code></pre></div></section></main></body></html>
+27
View File
@@ -0,0 +1,27 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">pub mod </span>ast;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">pub mod </span>dialect;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">pub mod </span>error;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">pub mod </span>parser;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">pub mod </span>parsers;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">pub mod </span>partition;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">pub mod </span>statements;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">pub mod </span>util;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">pub use </span>parsers::create_parser::{ENGINE, MAXVALUE, parse_json2_type_hint_path};
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">pub use </span>parsers::tql_parser::TQL;
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">pub use </span>parsers::with_tql_parser::{CteContent, HybridCteWith};
</code></pre></div></section></main></body></html>
+697
View File
@@ -0,0 +1,697 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parser.rs`."><title>parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::str::FromStr;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>chrono::{DateTime, Utc};
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>snafu::{OptionExt, ResultExt};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser::ast::{Ident, Query, Value};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>sqlparser::dialect::Dialect;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>sqlparser::parser::{Parser, ParserError, ParserOptions};
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>sqlparser::tokenizer::{Token, TokenWithSpan};
<a href=#24 id=24 data-nosnippet>24</a>
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::ast::{Expr, ObjectName};
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, InvalidSqlSnafu, <span class="prelude-ty">Result</span>, SyntaxSnafu};
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span><span class="kw">crate</span>::parsers::tql_parser;
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">use </span><span class="kw">crate</span>::statements::kill::Kill;
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">use </span><span class="kw">crate</span>::statements::transform_statements;
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">pub const </span>FLOW: <span class="kw-2">&amp;</span>str = <span class="string">"FLOW"</span>;
<a href=#33 id=33 data-nosnippet>33</a>
<a href=#34 id=34 data-nosnippet>34</a><span class="doccomment">/// SQL Parser options.
<a href=#35 id=35 data-nosnippet>35</a></span><span class="attr">#[derive(Clone, Debug, Default)]
<a href=#36 id=36 data-nosnippet>36</a></span><span class="kw">pub struct </span>ParseOptions {
<a href=#37 id=37 data-nosnippet>37</a> <span class="doccomment">/// If set, TQL parameter expressions containing `now()` will be evaluated
<a href=#38 id=38 data-nosnippet>38</a> /// against this scheduled time instead of wall-clock time.
<a href=#39 id=39 data-nosnippet>39</a> </span><span class="kw">pub </span>scheduled_time: <span class="prelude-ty">Option</span>&lt;DateTime&lt;Utc&gt;&gt;,
<a href=#40 id=40 data-nosnippet>40</a>}
<a href=#41 id=41 data-nosnippet>41</a>
<a href=#42 id=42 data-nosnippet>42</a><span class="doccomment">/// GrepTime SQL parser context, a simple wrapper for Datafusion SQL parser.
<a href=#43 id=43 data-nosnippet>43</a></span><span class="kw">pub struct </span>ParserContext&lt;<span class="lifetime">'a</span>&gt; {
<a href=#44 id=44 data-nosnippet>44</a> <span class="kw">pub</span>(<span class="kw">crate</span>) parser: Parser&lt;<span class="lifetime">'a</span>&gt;,
<a href=#45 id=45 data-nosnippet>45</a> <span class="kw">pub</span>(<span class="kw">crate</span>) sql: <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str,
<a href=#46 id=46 data-nosnippet>46</a> <span class="doccomment">/// Optional scheduled time for `now()` evaluation in TQL parameters.
<a href=#47 id=47 data-nosnippet>47</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) scheduled_time: <span class="prelude-ty">Option</span>&lt;DateTime&lt;Utc&gt;&gt;,
<a href=#48 id=48 data-nosnippet>48</a>}
<a href=#49 id=49 data-nosnippet>49</a>
<a href=#50 id=50 data-nosnippet>50</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#51 id=51 data-nosnippet>51</a> <span class="doccomment">/// Construct a new ParserContext.
<a href=#52 id=52 data-nosnippet>52</a> </span><span class="kw">pub fn </span>new&lt;<span class="lifetime">'a</span>&gt;(dialect: <span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="kw">dyn </span>Dialect, sql: <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str) -&gt; <span class="prelude-ty">Result</span>&lt;ParserContext&lt;<span class="lifetime">'a</span>&gt;&gt; {
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">let </span>parser = Parser::new(dialect)
<a href=#54 id=54 data-nosnippet>54</a> .with_options(ParserOptions::new().with_trailing_commas(<span class="bool-val">true</span>))
<a href=#55 id=55 data-nosnippet>55</a> .try_with_sql(sql)
<a href=#56 id=56 data-nosnippet>56</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a> <span class="prelude-val">Ok</span>(ParserContext {
<a href=#59 id=59 data-nosnippet>59</a> parser,
<a href=#60 id=60 data-nosnippet>60</a> sql,
<a href=#61 id=61 data-nosnippet>61</a> scheduled_time: <span class="prelude-val">None</span>,
<a href=#62 id=62 data-nosnippet>62</a> })
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a>
<a href=#65 id=65 data-nosnippet>65</a> <span class="doccomment">/// Parses parser context to Query.
<a href=#66 id=66 data-nosnippet>66</a> </span><span class="kw">pub fn </span>parser_query(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Box&lt;Query&gt;&gt; {
<a href=#67 id=67 data-nosnippet>67</a> <span class="self">self</span>.parser.parse_query().context(SyntaxSnafu)
<a href=#68 id=68 data-nosnippet>68</a> }
<a href=#69 id=69 data-nosnippet>69</a>
<a href=#70 id=70 data-nosnippet>70</a> <span class="doccomment">/// Parses SQL with given dialect
<a href=#71 id=71 data-nosnippet>71</a> </span><span class="kw">pub fn </span>create_with_dialect(
<a href=#72 id=72 data-nosnippet>72</a> sql: <span class="kw-2">&amp;</span>str,
<a href=#73 id=73 data-nosnippet>73</a> dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect,
<a href=#74 id=74 data-nosnippet>74</a> opts: ParseOptions,
<a href=#75 id=75 data-nosnippet>75</a> ) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;Statement&gt;&gt; {
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts: Vec&lt;Statement&gt; = Vec::new();
<a href=#77 id=77 data-nosnippet>77</a>
<a href=#78 id=78 data-nosnippet>78</a> <span class="kw">let </span><span class="kw-2">mut </span>parser_ctx = ParserContext::new(dialect, sql)<span class="question-mark">?</span>;
<a href=#79 id=79 data-nosnippet>79</a> parser_ctx.scheduled_time = opts.scheduled_time;
<a href=#80 id=80 data-nosnippet>80</a>
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">let </span><span class="kw-2">mut </span>expecting_statement_delimiter = <span class="bool-val">false</span>;
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">loop </span>{
<a href=#83 id=83 data-nosnippet>83</a> <span class="comment">// ignore empty statements (between successive statement delimiters)
<a href=#84 id=84 data-nosnippet>84</a> </span><span class="kw">while </span>parser_ctx.parser.consume_token(<span class="kw-2">&amp;</span>Token::SemiColon) {
<a href=#85 id=85 data-nosnippet>85</a> expecting_statement_delimiter = <span class="bool-val">false</span>;
<a href=#86 id=86 data-nosnippet>86</a> }
<a href=#87 id=87 data-nosnippet>87</a>
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">if </span>parser_ctx.parser.peek_token() == Token::EOF {
<a href=#89 id=89 data-nosnippet>89</a> <span class="kw">break</span>;
<a href=#90 id=90 data-nosnippet>90</a> }
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">if </span>expecting_statement_delimiter {
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">return </span>parser_ctx.unsupported(parser_ctx.peek_token_as_string());
<a href=#93 id=93 data-nosnippet>93</a> }
<a href=#94 id=94 data-nosnippet>94</a>
<a href=#95 id=95 data-nosnippet>95</a> <span class="kw">let </span>statement = parser_ctx.parse_statement()<span class="question-mark">?</span>;
<a href=#96 id=96 data-nosnippet>96</a> stmts.push(statement);
<a href=#97 id=97 data-nosnippet>97</a> expecting_statement_delimiter = <span class="bool-val">true</span>;
<a href=#98 id=98 data-nosnippet>98</a> }
<a href=#99 id=99 data-nosnippet>99</a>
<a href=#100 id=100 data-nosnippet>100</a> transform_statements(<span class="kw-2">&amp;mut </span>stmts)<span class="question-mark">?</span>;
<a href=#101 id=101 data-nosnippet>101</a>
<a href=#102 id=102 data-nosnippet>102</a> <span class="prelude-val">Ok</span>(stmts)
<a href=#103 id=103 data-nosnippet>103</a> }
<a href=#104 id=104 data-nosnippet>104</a>
<a href=#105 id=105 data-nosnippet>105</a> <span class="kw">pub fn </span>parse_table_name(sql: <span class="kw-2">&amp;</span>str, dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect) -&gt; <span class="prelude-ty">Result</span>&lt;ObjectName&gt; {
<a href=#106 id=106 data-nosnippet>106</a> <span class="kw">let </span>parser = Parser::new(dialect)
<a href=#107 id=107 data-nosnippet>107</a> .with_options(ParserOptions::new().with_trailing_commas(<span class="bool-val">true</span>))
<a href=#108 id=108 data-nosnippet>108</a> .try_with_sql(sql)
<a href=#109 id=109 data-nosnippet>109</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#110 id=110 data-nosnippet>110</a> ParserContext {
<a href=#111 id=111 data-nosnippet>111</a> parser,
<a href=#112 id=112 data-nosnippet>112</a> sql,
<a href=#113 id=113 data-nosnippet>113</a> scheduled_time: <span class="prelude-val">None</span>,
<a href=#114 id=114 data-nosnippet>114</a> }
<a href=#115 id=115 data-nosnippet>115</a> .intern_parse_table_name()
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a>
<a href=#118 id=118 data-nosnippet>118</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>intern_parse_table_name(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;ObjectName&gt; {
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">let </span>raw_table_name =
<a href=#120 id=120 data-nosnippet>120</a> <span class="self">self</span>.parser
<a href=#121 id=121 data-nosnippet>121</a> .parse_object_name(<span class="bool-val">false</span>)
<a href=#122 id=122 data-nosnippet>122</a> .context(error::UnexpectedSnafu {
<a href=#123 id=123 data-nosnippet>123</a> expected: <span class="string">"a table name"</span>,
<a href=#124 id=124 data-nosnippet>124</a> actual: <span class="self">self</span>.parser.peek_token().to_string(),
<a href=#125 id=125 data-nosnippet>125</a> })<span class="question-mark">?</span>;
<a href=#126 id=126 data-nosnippet>126</a> <span class="self">Self</span>::canonicalize_object_name(raw_table_name)
<a href=#127 id=127 data-nosnippet>127</a> }
<a href=#128 id=128 data-nosnippet>128</a>
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">pub fn </span>parse_function(sql: <span class="kw-2">&amp;</span>str, dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect) -&gt; <span class="prelude-ty">Result</span>&lt;Expr&gt; {
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">let </span><span class="kw-2">mut </span>parser = Parser::new(dialect)
<a href=#131 id=131 data-nosnippet>131</a> .with_options(ParserOptions::new().with_trailing_commas(<span class="bool-val">true</span>))
<a href=#132 id=132 data-nosnippet>132</a> .try_with_sql(sql)
<a href=#133 id=133 data-nosnippet>133</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#134 id=134 data-nosnippet>134</a>
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">let </span>function_name = parser.parse_identifier().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#136 id=136 data-nosnippet>136</a> parser
<a href=#137 id=137 data-nosnippet>137</a> .parse_function(<span class="macro">vec!</span>[function_name].into())
<a href=#138 id=138 data-nosnippet>138</a> .context(SyntaxSnafu)
<a href=#139 id=139 data-nosnippet>139</a> }
<a href=#140 id=140 data-nosnippet>140</a>
<a href=#141 id=141 data-nosnippet>141</a> <span class="doccomment">/// Parses parser context to a set of statements.
<a href=#142 id=142 data-nosnippet>142</a> </span><span class="kw">pub fn </span>parse_statement(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#143 id=143 data-nosnippet>143</a> <span class="kw">match </span><span class="self">self</span>.parser.peek_token().token {
<a href=#144 id=144 data-nosnippet>144</a> Token::Word(w) =&gt; <span class="kw">match </span>w.keyword {
<a href=#145 id=145 data-nosnippet>145</a> Keyword::CREATE =&gt; {
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#147 id=147 data-nosnippet>147</a> <span class="self">self</span>.parse_create()
<a href=#148 id=148 data-nosnippet>148</a> }
<a href=#149 id=149 data-nosnippet>149</a>
<a href=#150 id=150 data-nosnippet>150</a> Keyword::EXPLAIN =&gt; {
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#152 id=152 data-nosnippet>152</a> <span class="self">self</span>.parse_explain()
<a href=#153 id=153 data-nosnippet>153</a> }
<a href=#154 id=154 data-nosnippet>154</a>
<a href=#155 id=155 data-nosnippet>155</a> Keyword::SHOW =&gt; {
<a href=#156 id=156 data-nosnippet>156</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#157 id=157 data-nosnippet>157</a> <span class="self">self</span>.parse_show()
<a href=#158 id=158 data-nosnippet>158</a> }
<a href=#159 id=159 data-nosnippet>159</a>
<a href=#160 id=160 data-nosnippet>160</a> Keyword::DELETE =&gt; <span class="self">self</span>.parse_delete(),
<a href=#161 id=161 data-nosnippet>161</a>
<a href=#162 id=162 data-nosnippet>162</a> Keyword::DESCRIBE | Keyword::DESC =&gt; {
<a href=#163 id=163 data-nosnippet>163</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#164 id=164 data-nosnippet>164</a> <span class="self">self</span>.parse_describe()
<a href=#165 id=165 data-nosnippet>165</a> }
<a href=#166 id=166 data-nosnippet>166</a>
<a href=#167 id=167 data-nosnippet>167</a> Keyword::INSERT =&gt; <span class="self">self</span>.parse_insert(),
<a href=#168 id=168 data-nosnippet>168</a>
<a href=#169 id=169 data-nosnippet>169</a> Keyword::REPLACE =&gt; <span class="self">self</span>.parse_replace(),
<a href=#170 id=170 data-nosnippet>170</a>
<a href=#171 id=171 data-nosnippet>171</a> Keyword::SELECT | Keyword::VALUES =&gt; <span class="self">self</span>.parse_query(),
<a href=#172 id=172 data-nosnippet>172</a>
<a href=#173 id=173 data-nosnippet>173</a> Keyword::WITH =&gt; <span class="self">self</span>.parse_with_tql(),
<a href=#174 id=174 data-nosnippet>174</a>
<a href=#175 id=175 data-nosnippet>175</a> Keyword::ALTER =&gt; <span class="self">self</span>.parse_alter(),
<a href=#176 id=176 data-nosnippet>176</a>
<a href=#177 id=177 data-nosnippet>177</a> Keyword::DROP =&gt; <span class="self">self</span>.parse_drop(),
<a href=#178 id=178 data-nosnippet>178</a>
<a href=#179 id=179 data-nosnippet>179</a> Keyword::COPY =&gt; <span class="self">self</span>.parse_copy(),
<a href=#180 id=180 data-nosnippet>180</a>
<a href=#181 id=181 data-nosnippet>181</a> Keyword::TRUNCATE =&gt; <span class="self">self</span>.parse_truncate(),
<a href=#182 id=182 data-nosnippet>182</a>
<a href=#183 id=183 data-nosnippet>183</a> Keyword::COMMENT =&gt; <span class="self">self</span>.parse_comment(),
<a href=#184 id=184 data-nosnippet>184</a>
<a href=#185 id=185 data-nosnippet>185</a> Keyword::SET =&gt; <span class="self">self</span>.parse_set_variables(),
<a href=#186 id=186 data-nosnippet>186</a>
<a href=#187 id=187 data-nosnippet>187</a> Keyword::ADMIN =&gt; <span class="self">self</span>.parse_admin_command(),
<a href=#188 id=188 data-nosnippet>188</a>
<a href=#189 id=189 data-nosnippet>189</a> Keyword::NoKeyword
<a href=#190 id=190 data-nosnippet>190</a> <span class="kw">if </span>w.quote_style.is_none() &amp;&amp; w.value.to_uppercase() == tql_parser::TQL =&gt;
<a href=#191 id=191 data-nosnippet>191</a> {
<a href=#192 id=192 data-nosnippet>192</a> <span class="self">self</span>.parse_tql(<span class="bool-val">false</span>)
<a href=#193 id=193 data-nosnippet>193</a> }
<a href=#194 id=194 data-nosnippet>194</a>
<a href=#195 id=195 data-nosnippet>195</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#196 id=196 data-nosnippet>196</a> </span>Keyword::NoKeyword
<a href=#197 id=197 data-nosnippet>197</a> <span class="kw">if </span>w.quote_style.is_none() &amp;&amp; w.value.eq_ignore_ascii_case(<span class="string">"UNDROP"</span>) =&gt;
<a href=#198 id=198 data-nosnippet>198</a> {
<a href=#199 id=199 data-nosnippet>199</a> <span class="self">self</span>.parse_undrop_table()
<a href=#200 id=200 data-nosnippet>200</a> }
<a href=#201 id=201 data-nosnippet>201</a>
<a href=#202 id=202 data-nosnippet>202</a> Keyword::DECLARE =&gt; <span class="self">self</span>.parse_declare_cursor(),
<a href=#203 id=203 data-nosnippet>203</a>
<a href=#204 id=204 data-nosnippet>204</a> Keyword::FETCH =&gt; <span class="self">self</span>.parse_fetch_cursor(),
<a href=#205 id=205 data-nosnippet>205</a>
<a href=#206 id=206 data-nosnippet>206</a> Keyword::CLOSE =&gt; <span class="self">self</span>.parse_close_cursor(),
<a href=#207 id=207 data-nosnippet>207</a>
<a href=#208 id=208 data-nosnippet>208</a> Keyword::USE =&gt; {
<a href=#209 id=209 data-nosnippet>209</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#210 id=210 data-nosnippet>210</a>
<a href=#211 id=211 data-nosnippet>211</a> <span class="kw">let </span>database_name = <span class="self">self</span>.parser.parse_identifier().with_context(|<span class="kw">_</span>| {
<a href=#212 id=212 data-nosnippet>212</a> error::UnexpectedSnafu {
<a href=#213 id=213 data-nosnippet>213</a> expected: <span class="string">"a database name"</span>,
<a href=#214 id=214 data-nosnippet>214</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#215 id=215 data-nosnippet>215</a> }
<a href=#216 id=216 data-nosnippet>216</a> })<span class="question-mark">?</span>;
<a href=#217 id=217 data-nosnippet>217</a> <span class="prelude-val">Ok</span>(Statement::Use(
<a href=#218 id=218 data-nosnippet>218</a> <span class="self">Self</span>::canonicalize_identifier(database_name).value,
<a href=#219 id=219 data-nosnippet>219</a> ))
<a href=#220 id=220 data-nosnippet>220</a> }
<a href=#221 id=221 data-nosnippet>221</a>
<a href=#222 id=222 data-nosnippet>222</a> Keyword::KILL =&gt; {
<a href=#223 id=223 data-nosnippet>223</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#224 id=224 data-nosnippet>224</a> <span class="kw">let </span>kill = <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::QUERY) {
<a href=#225 id=225 data-nosnippet>225</a> <span class="comment">// MySQL KILL QUERY &lt;connection id&gt; statements
<a href=#226 id=226 data-nosnippet>226</a> </span><span class="kw">let </span>connection_id_exp =
<a href=#227 id=227 data-nosnippet>227</a> <span class="self">self</span>.parser.parse_number_value().with_context(|<span class="kw">_</span>| {
<a href=#228 id=228 data-nosnippet>228</a> error::UnexpectedSnafu {
<a href=#229 id=229 data-nosnippet>229</a> expected: <span class="string">"MySQL numeric connection id"</span>,
<a href=#230 id=230 data-nosnippet>230</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#231 id=231 data-nosnippet>231</a> }
<a href=#232 id=232 data-nosnippet>232</a> })<span class="question-mark">?</span>;
<a href=#233 id=233 data-nosnippet>233</a> <span class="kw">let </span>Value::Number(s, <span class="kw">_</span>) = connection_id_exp.value <span class="kw">else </span>{
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">return </span>error::UnexpectedTokenSnafu {
<a href=#235 id=235 data-nosnippet>235</a> expected: <span class="string">"MySQL numeric connection id"</span>,
<a href=#236 id=236 data-nosnippet>236</a> actual: connection_id_exp.to_string(),
<a href=#237 id=237 data-nosnippet>237</a> }
<a href=#238 id=238 data-nosnippet>238</a> .fail();
<a href=#239 id=239 data-nosnippet>239</a> };
<a href=#240 id=240 data-nosnippet>240</a>
<a href=#241 id=241 data-nosnippet>241</a> <span class="kw">let </span>connection_id = u32::from_str(<span class="kw-2">&amp;</span>s).map_err(|<span class="kw">_</span>| {
<a href=#242 id=242 data-nosnippet>242</a> error::UnexpectedTokenSnafu {
<a href=#243 id=243 data-nosnippet>243</a> expected: <span class="string">"MySQL numeric connection id"</span>,
<a href=#244 id=244 data-nosnippet>244</a> actual: s,
<a href=#245 id=245 data-nosnippet>245</a> }
<a href=#246 id=246 data-nosnippet>246</a> .build()
<a href=#247 id=247 data-nosnippet>247</a> })<span class="question-mark">?</span>;
<a href=#248 id=248 data-nosnippet>248</a> Kill::ConnectionId(connection_id)
<a href=#249 id=249 data-nosnippet>249</a> } <span class="kw">else </span>{
<a href=#250 id=250 data-nosnippet>250</a> <span class="kw">let </span>process_id_ident =
<a href=#251 id=251 data-nosnippet>251</a> <span class="self">self</span>.parser.parse_literal_string().with_context(|<span class="kw">_</span>| {
<a href=#252 id=252 data-nosnippet>252</a> error::UnexpectedSnafu {
<a href=#253 id=253 data-nosnippet>253</a> expected: <span class="string">"process id string literal"</span>,
<a href=#254 id=254 data-nosnippet>254</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#255 id=255 data-nosnippet>255</a> }
<a href=#256 id=256 data-nosnippet>256</a> })<span class="question-mark">?</span>;
<a href=#257 id=257 data-nosnippet>257</a> Kill::ProcessId(process_id_ident)
<a href=#258 id=258 data-nosnippet>258</a> };
<a href=#259 id=259 data-nosnippet>259</a>
<a href=#260 id=260 data-nosnippet>260</a> <span class="prelude-val">Ok</span>(Statement::Kill(kill))
<a href=#261 id=261 data-nosnippet>261</a> }
<a href=#262 id=262 data-nosnippet>262</a>
<a href=#263 id=263 data-nosnippet>263</a> <span class="kw">_ </span>=&gt; <span class="self">self</span>.unsupported(<span class="self">self</span>.peek_token_as_string()),
<a href=#264 id=264 data-nosnippet>264</a> },
<a href=#265 id=265 data-nosnippet>265</a> Token::LParen =&gt; <span class="self">self</span>.parse_query(),
<a href=#266 id=266 data-nosnippet>266</a> unexpected =&gt; <span class="self">self</span>.unsupported(unexpected.to_string()),
<a href=#267 id=267 data-nosnippet>267</a> }
<a href=#268 id=268 data-nosnippet>268</a> }
<a href=#269 id=269 data-nosnippet>269</a>
<a href=#270 id=270 data-nosnippet>270</a> <span class="doccomment">/// Parses MySQL style 'PREPARE stmt_name FROM stmt' into a (stmt_name, stmt) tuple.
<a href=#271 id=271 data-nosnippet>271</a> </span><span class="kw">pub fn </span>parse_mysql_prepare_stmt(sql: <span class="kw-2">&amp;</span>str, dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect) -&gt; <span class="prelude-ty">Result</span>&lt;(String, String)&gt; {
<a href=#272 id=272 data-nosnippet>272</a> ParserContext::new(dialect, sql)<span class="question-mark">?</span>.parse_mysql_prepare()
<a href=#273 id=273 data-nosnippet>273</a> }
<a href=#274 id=274 data-nosnippet>274</a>
<a href=#275 id=275 data-nosnippet>275</a> <span class="doccomment">/// Parses MySQL style 'EXECUTE stmt_name USING param_list' into a stmt_name string and a list of parameters.
<a href=#276 id=276 data-nosnippet>276</a> </span><span class="kw">pub fn </span>parse_mysql_execute_stmt(
<a href=#277 id=277 data-nosnippet>277</a> sql: <span class="kw-2">&amp;</span>str,
<a href=#278 id=278 data-nosnippet>278</a> dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect,
<a href=#279 id=279 data-nosnippet>279</a> ) -&gt; <span class="prelude-ty">Result</span>&lt;(String, Vec&lt;Expr&gt;)&gt; {
<a href=#280 id=280 data-nosnippet>280</a> ParserContext::new(dialect, sql)<span class="question-mark">?</span>.parse_mysql_execute()
<a href=#281 id=281 data-nosnippet>281</a> }
<a href=#282 id=282 data-nosnippet>282</a>
<a href=#283 id=283 data-nosnippet>283</a> <span class="doccomment">/// Parses MySQL style 'DEALLOCATE stmt_name' into a stmt_name string.
<a href=#284 id=284 data-nosnippet>284</a> </span><span class="kw">pub fn </span>parse_mysql_deallocate_stmt(sql: <span class="kw-2">&amp;</span>str, dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect) -&gt; <span class="prelude-ty">Result</span>&lt;String&gt; {
<a href=#285 id=285 data-nosnippet>285</a> ParserContext::new(dialect, sql)<span class="question-mark">?</span>.parse_deallocate()
<a href=#286 id=286 data-nosnippet>286</a> }
<a href=#287 id=287 data-nosnippet>287</a>
<a href=#288 id=288 data-nosnippet>288</a> <span class="doccomment">/// Raises an "unsupported statement" error.
<a href=#289 id=289 data-nosnippet>289</a> </span><span class="kw">pub fn </span>unsupported&lt;T&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, keyword: String) -&gt; <span class="prelude-ty">Result</span>&lt;T&gt; {
<a href=#290 id=290 data-nosnippet>290</a> error::UnsupportedSnafu { keyword }.fail()
<a href=#291 id=291 data-nosnippet>291</a> }
<a href=#292 id=292 data-nosnippet>292</a>
<a href=#293 id=293 data-nosnippet>293</a> <span class="comment">// Report unexpected token
<a href=#294 id=294 data-nosnippet>294</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>expected&lt;T&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, expected: <span class="kw-2">&amp;</span>str, found: TokenWithSpan) -&gt; <span class="prelude-ty">Result</span>&lt;T&gt; {
<a href=#295 id=295 data-nosnippet>295</a> <span class="prelude-val">Err</span>(ParserError::ParserError(<span class="macro">format!</span>(
<a href=#296 id=296 data-nosnippet>296</a> <span class="string">"Expected {expected}, found: {found}"</span>,
<a href=#297 id=297 data-nosnippet>297</a> )))
<a href=#298 id=298 data-nosnippet>298</a> .context(SyntaxSnafu)
<a href=#299 id=299 data-nosnippet>299</a> }
<a href=#300 id=300 data-nosnippet>300</a>
<a href=#301 id=301 data-nosnippet>301</a> <span class="kw">pub fn </span>matches_keyword(<span class="kw-2">&amp;mut </span><span class="self">self</span>, expected: Keyword) -&gt; bool {
<a href=#302 id=302 data-nosnippet>302</a> <span class="kw">match </span><span class="self">self</span>.parser.peek_token().token {
<a href=#303 id=303 data-nosnippet>303</a> Token::Word(w) =&gt; w.keyword == expected,
<a href=#304 id=304 data-nosnippet>304</a> <span class="kw">_ </span>=&gt; <span class="bool-val">false</span>,
<a href=#305 id=305 data-nosnippet>305</a> }
<a href=#306 id=306 data-nosnippet>306</a> }
<a href=#307 id=307 data-nosnippet>307</a>
<a href=#308 id=308 data-nosnippet>308</a> <span class="kw">pub fn </span>consume_token(<span class="kw-2">&amp;mut </span><span class="self">self</span>, expected: <span class="kw-2">&amp;</span>str) -&gt; bool {
<a href=#309 id=309 data-nosnippet>309</a> <span class="kw">if </span><span class="self">self</span>.peek_token_as_string().to_uppercase() == <span class="kw-2">*</span>expected.to_uppercase() {
<a href=#310 id=310 data-nosnippet>310</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#311 id=311 data-nosnippet>311</a> <span class="bool-val">true
<a href=#312 id=312 data-nosnippet>312</a> </span>} <span class="kw">else </span>{
<a href=#313 id=313 data-nosnippet>313</a> <span class="bool-val">false
<a href=#314 id=314 data-nosnippet>314</a> </span>}
<a href=#315 id=315 data-nosnippet>315</a> }
<a href=#316 id=316 data-nosnippet>316</a>
<a href=#317 id=317 data-nosnippet>317</a> <span class="attr">#[inline]
<a href=#318 id=318 data-nosnippet>318</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>peek_token_as_string(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; String {
<a href=#319 id=319 data-nosnippet>319</a> <span class="self">self</span>.parser.peek_token().to_string()
<a href=#320 id=320 data-nosnippet>320</a> }
<a href=#321 id=321 data-nosnippet>321</a>
<a href=#322 id=322 data-nosnippet>322</a> <span class="doccomment">/// Canonicalize the identifier to lowercase if it's not quoted.
<a href=#323 id=323 data-nosnippet>323</a> </span><span class="kw">pub fn </span>canonicalize_identifier(ident: Ident) -&gt; Ident {
<a href=#324 id=324 data-nosnippet>324</a> <span class="kw">if </span>ident.quote_style.is_some() {
<a href=#325 id=325 data-nosnippet>325</a> ident
<a href=#326 id=326 data-nosnippet>326</a> } <span class="kw">else </span>{
<a href=#327 id=327 data-nosnippet>327</a> Ident::new(ident.value.to_lowercase())
<a href=#328 id=328 data-nosnippet>328</a> }
<a href=#329 id=329 data-nosnippet>329</a> }
<a href=#330 id=330 data-nosnippet>330</a>
<a href=#331 id=331 data-nosnippet>331</a> <span class="doccomment">/// Like [canonicalize_identifier] but for [ObjectName].
<a href=#332 id=332 data-nosnippet>332</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>canonicalize_object_name(object_name: ObjectName) -&gt; <span class="prelude-ty">Result</span>&lt;ObjectName&gt; {
<a href=#333 id=333 data-nosnippet>333</a> object_name
<a href=#334 id=334 data-nosnippet>334</a> .<span class="number">0
<a href=#335 id=335 data-nosnippet>335</a> </span>.into_iter()
<a href=#336 id=336 data-nosnippet>336</a> .map(|x| {
<a href=#337 id=337 data-nosnippet>337</a> x.as_ident()
<a href=#338 id=338 data-nosnippet>338</a> .cloned()
<a href=#339 id=339 data-nosnippet>339</a> .map(<span class="self">Self</span>::canonicalize_identifier)
<a href=#340 id=340 data-nosnippet>340</a> .with_context(|| InvalidSqlSnafu {
<a href=#341 id=341 data-nosnippet>341</a> msg: <span class="macro">format!</span>(<span class="string">"not an ident: '{x}'"</span>),
<a href=#342 id=342 data-nosnippet>342</a> })
<a href=#343 id=343 data-nosnippet>343</a> })
<a href=#344 id=344 data-nosnippet>344</a> .collect::&lt;<span class="prelude-ty">Result</span>&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;&gt;()
<a href=#345 id=345 data-nosnippet>345</a> .map(Into::into)
<a href=#346 id=346 data-nosnippet>346</a> }
<a href=#347 id=347 data-nosnippet>347</a>
<a href=#348 id=348 data-nosnippet>348</a> <span class="doccomment">/// Simply a shortcut for sqlparser's same name method `parse_object_name`,
<a href=#349 id=349 data-nosnippet>349</a> /// but with constant argument "false".
<a href=#350 id=350 data-nosnippet>350</a> /// Because the argument is always "false" for us (it's introduced by BigQuery),
<a href=#351 id=351 data-nosnippet>351</a> /// we don't want to write it again and again.
<a href=#352 id=352 data-nosnippet>352</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_object_name(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; std::result::Result&lt;ObjectName, ParserError&gt; {
<a href=#353 id=353 data-nosnippet>353</a> <span class="self">self</span>.parser.parse_object_name(<span class="bool-val">false</span>)
<a href=#354 id=354 data-nosnippet>354</a> }
<a href=#355 id=355 data-nosnippet>355</a>}
<a href=#356 id=356 data-nosnippet>356</a>
<a href=#357 id=357 data-nosnippet>357</a><span class="attr">#[cfg(test)]
<a href=#358 id=358 data-nosnippet>358</a></span><span class="kw">mod </span>tests {
<a href=#359 id=359 data-nosnippet>359</a>
<a href=#360 id=360 data-nosnippet>360</a> <span class="kw">use </span>datatypes::prelude::ConcreteDataType;
<a href=#361 id=361 data-nosnippet>361</a> <span class="kw">use </span>sqlparser::dialect::MySqlDialect;
<a href=#362 id=362 data-nosnippet>362</a>
<a href=#363 id=363 data-nosnippet>363</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#364 id=364 data-nosnippet>364</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#365 id=365 data-nosnippet>365</a> <span class="kw">use </span><span class="kw">crate</span>::statements::create::CreateTable;
<a href=#366 id=366 data-nosnippet>366</a> <span class="kw">use </span><span class="kw">crate</span>::statements::sql_data_type_to_concrete_data_type;
<a href=#367 id=367 data-nosnippet>367</a>
<a href=#368 id=368 data-nosnippet>368</a> <span class="kw">fn </span>test_timestamp_precision(sql: <span class="kw-2">&amp;</span>str, expected_type: ConcreteDataType) {
<a href=#369 id=369 data-nosnippet>369</a> <span class="kw">match </span>ParserContext::create_with_dialect(
<a href=#370 id=370 data-nosnippet>370</a> sql,
<a href=#371 id=371 data-nosnippet>371</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#372 id=372 data-nosnippet>372</a> ParseOptions::default(),
<a href=#373 id=373 data-nosnippet>373</a> )
<a href=#374 id=374 data-nosnippet>374</a> .unwrap()
<a href=#375 id=375 data-nosnippet>375</a> .pop()
<a href=#376 id=376 data-nosnippet>376</a> .unwrap()
<a href=#377 id=377 data-nosnippet>377</a> {
<a href=#378 id=378 data-nosnippet>378</a> Statement::CreateTable(CreateTable { columns, .. }) =&gt; {
<a href=#379 id=379 data-nosnippet>379</a> <span class="kw">let </span>ts_col = columns.first().unwrap();
<a href=#380 id=380 data-nosnippet>380</a> <span class="macro">assert_eq!</span>(
<a href=#381 id=381 data-nosnippet>381</a> expected_type,
<a href=#382 id=382 data-nosnippet>382</a> sql_data_type_to_concrete_data_type(ts_col.data_type()).unwrap()
<a href=#383 id=383 data-nosnippet>383</a> );
<a href=#384 id=384 data-nosnippet>384</a> }
<a href=#385 id=385 data-nosnippet>385</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#386 id=386 data-nosnippet>386</a> }
<a href=#387 id=387 data-nosnippet>387</a> }
<a href=#388 id=388 data-nosnippet>388</a>
<a href=#389 id=389 data-nosnippet>389</a> <span class="attr">#[test]
<a href=#390 id=390 data-nosnippet>390</a> </span><span class="kw">pub fn </span>test_create_table_with_precision() {
<a href=#391 id=391 data-nosnippet>391</a> test_timestamp_precision(
<a href=#392 id=392 data-nosnippet>392</a> <span class="string">"create table demo (ts timestamp time index, cnt int);"</span>,
<a href=#393 id=393 data-nosnippet>393</a> ConcreteDataType::timestamp_millisecond_datatype(),
<a href=#394 id=394 data-nosnippet>394</a> );
<a href=#395 id=395 data-nosnippet>395</a> test_timestamp_precision(
<a href=#396 id=396 data-nosnippet>396</a> <span class="string">"create table demo (ts timestamp(0) time index, cnt int);"</span>,
<a href=#397 id=397 data-nosnippet>397</a> ConcreteDataType::timestamp_second_datatype(),
<a href=#398 id=398 data-nosnippet>398</a> );
<a href=#399 id=399 data-nosnippet>399</a> test_timestamp_precision(
<a href=#400 id=400 data-nosnippet>400</a> <span class="string">"create table demo (ts timestamp(3) time index, cnt int);"</span>,
<a href=#401 id=401 data-nosnippet>401</a> ConcreteDataType::timestamp_millisecond_datatype(),
<a href=#402 id=402 data-nosnippet>402</a> );
<a href=#403 id=403 data-nosnippet>403</a> test_timestamp_precision(
<a href=#404 id=404 data-nosnippet>404</a> <span class="string">"create table demo (ts timestamp(6) time index, cnt int);"</span>,
<a href=#405 id=405 data-nosnippet>405</a> ConcreteDataType::timestamp_microsecond_datatype(),
<a href=#406 id=406 data-nosnippet>406</a> );
<a href=#407 id=407 data-nosnippet>407</a> test_timestamp_precision(
<a href=#408 id=408 data-nosnippet>408</a> <span class="string">"create table demo (ts timestamp(9) time index, cnt int);"</span>,
<a href=#409 id=409 data-nosnippet>409</a> ConcreteDataType::timestamp_nanosecond_datatype(),
<a href=#410 id=410 data-nosnippet>410</a> );
<a href=#411 id=411 data-nosnippet>411</a> }
<a href=#412 id=412 data-nosnippet>412</a>
<a href=#413 id=413 data-nosnippet>413</a> <span class="attr">#[test]
<a href=#414 id=414 data-nosnippet>414</a> #[should_panic]
<a href=#415 id=415 data-nosnippet>415</a> </span><span class="kw">pub fn </span>test_create_table_with_invalid_precision() {
<a href=#416 id=416 data-nosnippet>416</a> test_timestamp_precision(
<a href=#417 id=417 data-nosnippet>417</a> <span class="string">"create table demo (ts timestamp(1) time index, cnt int);"</span>,
<a href=#418 id=418 data-nosnippet>418</a> ConcreteDataType::timestamp_millisecond_datatype(),
<a href=#419 id=419 data-nosnippet>419</a> );
<a href=#420 id=420 data-nosnippet>420</a> }
<a href=#421 id=421 data-nosnippet>421</a>
<a href=#422 id=422 data-nosnippet>422</a> <span class="attr">#[test]
<a href=#423 id=423 data-nosnippet>423</a> </span><span class="kw">pub fn </span>test_parse_table_name() {
<a href=#424 id=424 data-nosnippet>424</a> <span class="kw">let </span>table_name = <span class="string">"a.b.c"</span>;
<a href=#425 id=425 data-nosnippet>425</a>
<a href=#426 id=426 data-nosnippet>426</a> <span class="kw">let </span>object_name =
<a href=#427 id=427 data-nosnippet>427</a> ParserContext::parse_table_name(table_name, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#428 id=428 data-nosnippet>428</a>
<a href=#429 id=429 data-nosnippet>429</a> <span class="macro">assert_eq!</span>(object_name.<span class="number">0</span>.len(), <span class="number">3</span>);
<a href=#430 id=430 data-nosnippet>430</a> <span class="macro">assert_eq!</span>(object_name.to_string(), table_name);
<a href=#431 id=431 data-nosnippet>431</a>
<a href=#432 id=432 data-nosnippet>432</a> <span class="kw">let </span>table_name = <span class="string">"a.b"</span>;
<a href=#433 id=433 data-nosnippet>433</a>
<a href=#434 id=434 data-nosnippet>434</a> <span class="kw">let </span>object_name =
<a href=#435 id=435 data-nosnippet>435</a> ParserContext::parse_table_name(table_name, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#436 id=436 data-nosnippet>436</a>
<a href=#437 id=437 data-nosnippet>437</a> <span class="macro">assert_eq!</span>(object_name.<span class="number">0</span>.len(), <span class="number">2</span>);
<a href=#438 id=438 data-nosnippet>438</a> <span class="macro">assert_eq!</span>(object_name.to_string(), table_name);
<a href=#439 id=439 data-nosnippet>439</a>
<a href=#440 id=440 data-nosnippet>440</a> <span class="kw">let </span>table_name = <span class="string">"Test.\"public-test\""</span>;
<a href=#441 id=441 data-nosnippet>441</a>
<a href=#442 id=442 data-nosnippet>442</a> <span class="kw">let </span>object_name =
<a href=#443 id=443 data-nosnippet>443</a> ParserContext::parse_table_name(table_name, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#444 id=444 data-nosnippet>444</a>
<a href=#445 id=445 data-nosnippet>445</a> <span class="macro">assert_eq!</span>(object_name.<span class="number">0</span>.len(), <span class="number">2</span>);
<a href=#446 id=446 data-nosnippet>446</a> <span class="macro">assert_eq!</span>(object_name.to_string(), table_name.to_ascii_lowercase());
<a href=#447 id=447 data-nosnippet>447</a>
<a href=#448 id=448 data-nosnippet>448</a> <span class="kw">let </span>table_name = <span class="string">"HelloWorld"</span>;
<a href=#449 id=449 data-nosnippet>449</a>
<a href=#450 id=450 data-nosnippet>450</a> <span class="kw">let </span>object_name =
<a href=#451 id=451 data-nosnippet>451</a> ParserContext::parse_table_name(table_name, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#452 id=452 data-nosnippet>452</a>
<a href=#453 id=453 data-nosnippet>453</a> <span class="macro">assert_eq!</span>(object_name.<span class="number">0</span>.len(), <span class="number">1</span>);
<a href=#454 id=454 data-nosnippet>454</a> <span class="macro">assert_eq!</span>(object_name.to_string(), table_name.to_ascii_lowercase());
<a href=#455 id=455 data-nosnippet>455</a> }
<a href=#456 id=456 data-nosnippet>456</a>
<a href=#457 id=457 data-nosnippet>457</a> <span class="attr">#[test]
<a href=#458 id=458 data-nosnippet>458</a> </span><span class="kw">pub fn </span>test_parse_mysql_prepare_stmt() {
<a href=#459 id=459 data-nosnippet>459</a> <span class="kw">let </span>sql = <span class="string">"PREPARE stmt1 FROM 'SELECT * FROM t1 WHERE id = ?';"</span>;
<a href=#460 id=460 data-nosnippet>460</a> <span class="kw">let </span>(stmt_name, stmt) =
<a href=#461 id=461 data-nosnippet>461</a> ParserContext::parse_mysql_prepare_stmt(sql, <span class="kw-2">&amp;</span>MySqlDialect {}).unwrap();
<a href=#462 id=462 data-nosnippet>462</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt1"</span>);
<a href=#463 id=463 data-nosnippet>463</a> <span class="macro">assert_eq!</span>(stmt, <span class="string">"SELECT * FROM t1 WHERE id = ?"</span>);
<a href=#464 id=464 data-nosnippet>464</a>
<a href=#465 id=465 data-nosnippet>465</a> <span class="kw">let </span>sql = <span class="string">"PREPARE stmt2 FROM \"SELECT * FROM t1 WHERE id = ?\""</span>;
<a href=#466 id=466 data-nosnippet>466</a> <span class="kw">let </span>(stmt_name, stmt) =
<a href=#467 id=467 data-nosnippet>467</a> ParserContext::parse_mysql_prepare_stmt(sql, <span class="kw-2">&amp;</span>MySqlDialect {}).unwrap();
<a href=#468 id=468 data-nosnippet>468</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt2"</span>);
<a href=#469 id=469 data-nosnippet>469</a> <span class="macro">assert_eq!</span>(stmt, <span class="string">"SELECT * FROM t1 WHERE id = ?"</span>);
<a href=#470 id=470 data-nosnippet>470</a> }
<a href=#471 id=471 data-nosnippet>471</a>
<a href=#472 id=472 data-nosnippet>472</a> <span class="attr">#[test]
<a href=#473 id=473 data-nosnippet>473</a> </span><span class="kw">pub fn </span>test_parse_mysql_execute_stmt() {
<a href=#474 id=474 data-nosnippet>474</a> <span class="kw">let </span>sql = <span class="string">"EXECUTE stmt1 USING 1, 'hello';"</span>;
<a href=#475 id=475 data-nosnippet>475</a> <span class="kw">let </span>(stmt_name, params) =
<a href=#476 id=476 data-nosnippet>476</a> ParserContext::parse_mysql_execute_stmt(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#477 id=477 data-nosnippet>477</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt1"</span>);
<a href=#478 id=478 data-nosnippet>478</a> <span class="macro">assert_eq!</span>(params.len(), <span class="number">2</span>);
<a href=#479 id=479 data-nosnippet>479</a> <span class="macro">assert_eq!</span>(params[<span class="number">0</span>].to_string(), <span class="string">"1"</span>);
<a href=#480 id=480 data-nosnippet>480</a> <span class="macro">assert_eq!</span>(params[<span class="number">1</span>].to_string(), <span class="string">"'hello'"</span>);
<a href=#481 id=481 data-nosnippet>481</a>
<a href=#482 id=482 data-nosnippet>482</a> <span class="kw">let </span>sql = <span class="string">"EXECUTE stmt2;"</span>;
<a href=#483 id=483 data-nosnippet>483</a> <span class="kw">let </span>(stmt_name, params) =
<a href=#484 id=484 data-nosnippet>484</a> ParserContext::parse_mysql_execute_stmt(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#485 id=485 data-nosnippet>485</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt2"</span>);
<a href=#486 id=486 data-nosnippet>486</a> <span class="macro">assert_eq!</span>(params.len(), <span class="number">0</span>);
<a href=#487 id=487 data-nosnippet>487</a>
<a href=#488 id=488 data-nosnippet>488</a> <span class="kw">let </span>sql = <span class="string">"EXECUTE stmt3 USING 231, 'hello', \"2003-03-1\", NULL, ;"</span>;
<a href=#489 id=489 data-nosnippet>489</a> <span class="kw">let </span>(stmt_name, params) =
<a href=#490 id=490 data-nosnippet>490</a> ParserContext::parse_mysql_execute_stmt(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#491 id=491 data-nosnippet>491</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt3"</span>);
<a href=#492 id=492 data-nosnippet>492</a> <span class="macro">assert_eq!</span>(params.len(), <span class="number">4</span>);
<a href=#493 id=493 data-nosnippet>493</a> <span class="macro">assert_eq!</span>(params[<span class="number">0</span>].to_string(), <span class="string">"231"</span>);
<a href=#494 id=494 data-nosnippet>494</a> <span class="macro">assert_eq!</span>(params[<span class="number">1</span>].to_string(), <span class="string">"'hello'"</span>);
<a href=#495 id=495 data-nosnippet>495</a> <span class="macro">assert_eq!</span>(params[<span class="number">2</span>].to_string(), <span class="string">"\"2003-03-1\""</span>);
<a href=#496 id=496 data-nosnippet>496</a> <span class="macro">assert_eq!</span>(params[<span class="number">3</span>].to_string(), <span class="string">"NULL"</span>);
<a href=#497 id=497 data-nosnippet>497</a> }
<a href=#498 id=498 data-nosnippet>498</a>
<a href=#499 id=499 data-nosnippet>499</a> <span class="attr">#[test]
<a href=#500 id=500 data-nosnippet>500</a> </span><span class="kw">pub fn </span>test_parse_mysql_deallocate_stmt() {
<a href=#501 id=501 data-nosnippet>501</a> <span class="kw">let </span>sql = <span class="string">"DEALLOCATE stmt1;"</span>;
<a href=#502 id=502 data-nosnippet>502</a> <span class="kw">let </span>stmt_name = ParserContext::parse_mysql_deallocate_stmt(sql, <span class="kw-2">&amp;</span>MySqlDialect {}).unwrap();
<a href=#503 id=503 data-nosnippet>503</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt1"</span>);
<a href=#504 id=504 data-nosnippet>504</a>
<a href=#505 id=505 data-nosnippet>505</a> <span class="kw">let </span>sql = <span class="string">"DEALLOCATE stmt2"</span>;
<a href=#506 id=506 data-nosnippet>506</a> <span class="kw">let </span>stmt_name = ParserContext::parse_mysql_deallocate_stmt(sql, <span class="kw-2">&amp;</span>MySqlDialect {}).unwrap();
<a href=#507 id=507 data-nosnippet>507</a> <span class="macro">assert_eq!</span>(stmt_name, <span class="string">"stmt2"</span>);
<a href=#508 id=508 data-nosnippet>508</a> }
<a href=#509 id=509 data-nosnippet>509</a>
<a href=#510 id=510 data-nosnippet>510</a> <span class="attr">#[test]
<a href=#511 id=511 data-nosnippet>511</a> </span><span class="kw">pub fn </span>test_parse_kill_query_statement() {
<a href=#512 id=512 data-nosnippet>512</a> <span class="kw">use </span><span class="kw">crate</span>::statements::kill::Kill;
<a href=#513 id=513 data-nosnippet>513</a>
<a href=#514 id=514 data-nosnippet>514</a> <span class="comment">// Test MySQL-style KILL QUERY with connection ID
<a href=#515 id=515 data-nosnippet>515</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY 123"</span>;
<a href=#516 id=516 data-nosnippet>516</a> <span class="kw">let </span>statements =
<a href=#517 id=517 data-nosnippet>517</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#518 id=518 data-nosnippet>518</a> .unwrap();
<a href=#519 id=519 data-nosnippet>519</a>
<a href=#520 id=520 data-nosnippet>520</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#521 id=521 data-nosnippet>521</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#522 id=522 data-nosnippet>522</a> Statement::Kill(Kill::ConnectionId(connection_id)) =&gt; {
<a href=#523 id=523 data-nosnippet>523</a> <span class="macro">assert_eq!</span>(<span class="kw-2">*</span>connection_id, <span class="number">123</span>);
<a href=#524 id=524 data-nosnippet>524</a> }
<a href=#525 id=525 data-nosnippet>525</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ConnectionId statement"</span>),
<a href=#526 id=526 data-nosnippet>526</a> }
<a href=#527 id=527 data-nosnippet>527</a>
<a href=#528 id=528 data-nosnippet>528</a> <span class="comment">// Test with larger connection ID
<a href=#529 id=529 data-nosnippet>529</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY 999999"</span>;
<a href=#530 id=530 data-nosnippet>530</a> <span class="kw">let </span>statements =
<a href=#531 id=531 data-nosnippet>531</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#532 id=532 data-nosnippet>532</a> .unwrap();
<a href=#533 id=533 data-nosnippet>533</a>
<a href=#534 id=534 data-nosnippet>534</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#535 id=535 data-nosnippet>535</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#536 id=536 data-nosnippet>536</a> Statement::Kill(Kill::ConnectionId(connection_id)) =&gt; {
<a href=#537 id=537 data-nosnippet>537</a> <span class="macro">assert_eq!</span>(<span class="kw-2">*</span>connection_id, <span class="number">999999</span>);
<a href=#538 id=538 data-nosnippet>538</a> }
<a href=#539 id=539 data-nosnippet>539</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ConnectionId statement"</span>),
<a href=#540 id=540 data-nosnippet>540</a> }
<a href=#541 id=541 data-nosnippet>541</a> }
<a href=#542 id=542 data-nosnippet>542</a>
<a href=#543 id=543 data-nosnippet>543</a> <span class="attr">#[test]
<a href=#544 id=544 data-nosnippet>544</a> </span><span class="kw">pub fn </span>test_parse_kill_process_statement() {
<a href=#545 id=545 data-nosnippet>545</a> <span class="kw">use </span><span class="kw">crate</span>::statements::kill::Kill;
<a href=#546 id=546 data-nosnippet>546</a>
<a href=#547 id=547 data-nosnippet>547</a> <span class="comment">// Test KILL with process ID string
<a href=#548 id=548 data-nosnippet>548</a> </span><span class="kw">let </span>sql = <span class="string">"KILL 'process-123'"</span>;
<a href=#549 id=549 data-nosnippet>549</a> <span class="kw">let </span>statements =
<a href=#550 id=550 data-nosnippet>550</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#551 id=551 data-nosnippet>551</a> .unwrap();
<a href=#552 id=552 data-nosnippet>552</a>
<a href=#553 id=553 data-nosnippet>553</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#554 id=554 data-nosnippet>554</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#555 id=555 data-nosnippet>555</a> Statement::Kill(Kill::ProcessId(process_id)) =&gt; {
<a href=#556 id=556 data-nosnippet>556</a> <span class="macro">assert_eq!</span>(process_id, <span class="string">"process-123"</span>);
<a href=#557 id=557 data-nosnippet>557</a> }
<a href=#558 id=558 data-nosnippet>558</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ProcessId statement"</span>),
<a href=#559 id=559 data-nosnippet>559</a> }
<a href=#560 id=560 data-nosnippet>560</a>
<a href=#561 id=561 data-nosnippet>561</a> <span class="comment">// Test with double quotes
<a href=#562 id=562 data-nosnippet>562</a> </span><span class="kw">let </span>sql = <span class="string">"KILL \"process-456\""</span>;
<a href=#563 id=563 data-nosnippet>563</a> <span class="kw">let </span>statements =
<a href=#564 id=564 data-nosnippet>564</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#565 id=565 data-nosnippet>565</a> .unwrap();
<a href=#566 id=566 data-nosnippet>566</a>
<a href=#567 id=567 data-nosnippet>567</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#568 id=568 data-nosnippet>568</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#569 id=569 data-nosnippet>569</a> Statement::Kill(Kill::ProcessId(process_id)) =&gt; {
<a href=#570 id=570 data-nosnippet>570</a> <span class="macro">assert_eq!</span>(process_id, <span class="string">"process-456"</span>);
<a href=#571 id=571 data-nosnippet>571</a> }
<a href=#572 id=572 data-nosnippet>572</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ProcessId statement"</span>),
<a href=#573 id=573 data-nosnippet>573</a> }
<a href=#574 id=574 data-nosnippet>574</a>
<a href=#575 id=575 data-nosnippet>575</a> <span class="comment">// Test with UUID-like process ID
<a href=#576 id=576 data-nosnippet>576</a> </span><span class="kw">let </span>sql = <span class="string">"KILL 'f47ac10b-58cc-4372-a567-0e02b2c3d479'"</span>;
<a href=#577 id=577 data-nosnippet>577</a> <span class="kw">let </span>statements =
<a href=#578 id=578 data-nosnippet>578</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#579 id=579 data-nosnippet>579</a> .unwrap();
<a href=#580 id=580 data-nosnippet>580</a>
<a href=#581 id=581 data-nosnippet>581</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#582 id=582 data-nosnippet>582</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#583 id=583 data-nosnippet>583</a> Statement::Kill(Kill::ProcessId(process_id)) =&gt; {
<a href=#584 id=584 data-nosnippet>584</a> <span class="macro">assert_eq!</span>(process_id, <span class="string">"f47ac10b-58cc-4372-a567-0e02b2c3d479"</span>);
<a href=#585 id=585 data-nosnippet>585</a> }
<a href=#586 id=586 data-nosnippet>586</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ProcessId statement"</span>),
<a href=#587 id=587 data-nosnippet>587</a> }
<a href=#588 id=588 data-nosnippet>588</a> }
<a href=#589 id=589 data-nosnippet>589</a>
<a href=#590 id=590 data-nosnippet>590</a> <span class="attr">#[test]
<a href=#591 id=591 data-nosnippet>591</a> </span><span class="kw">pub fn </span>test_parse_kill_statement_errors() {
<a href=#592 id=592 data-nosnippet>592</a> <span class="comment">// Test KILL QUERY without connection ID
<a href=#593 id=593 data-nosnippet>593</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY"</span>;
<a href=#594 id=594 data-nosnippet>594</a> <span class="kw">let </span>result =
<a href=#595 id=595 data-nosnippet>595</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#596 id=596 data-nosnippet>596</a> <span class="macro">assert!</span>(result.is_err());
<a href=#597 id=597 data-nosnippet>597</a>
<a href=#598 id=598 data-nosnippet>598</a> <span class="comment">// Test KILL QUERY with non-numeric connection ID
<a href=#599 id=599 data-nosnippet>599</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY 'not-a-number'"</span>;
<a href=#600 id=600 data-nosnippet>600</a> <span class="kw">let </span>result =
<a href=#601 id=601 data-nosnippet>601</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#602 id=602 data-nosnippet>602</a> <span class="macro">assert!</span>(result.is_err());
<a href=#603 id=603 data-nosnippet>603</a>
<a href=#604 id=604 data-nosnippet>604</a> <span class="comment">// Test KILL without any argument
<a href=#605 id=605 data-nosnippet>605</a> </span><span class="kw">let </span>sql = <span class="string">"KILL"</span>;
<a href=#606 id=606 data-nosnippet>606</a> <span class="kw">let </span>result =
<a href=#607 id=607 data-nosnippet>607</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#608 id=608 data-nosnippet>608</a> <span class="macro">assert!</span>(result.is_err());
<a href=#609 id=609 data-nosnippet>609</a>
<a href=#610 id=610 data-nosnippet>610</a> <span class="comment">// Test KILL QUERY with connection ID that's too large for u32
<a href=#611 id=611 data-nosnippet>611</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY 4294967296"</span>; <span class="comment">// u32::MAX + 1
<a href=#612 id=612 data-nosnippet>612</a> </span><span class="kw">let </span>result =
<a href=#613 id=613 data-nosnippet>613</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#614 id=614 data-nosnippet>614</a> <span class="macro">assert!</span>(result.is_err());
<a href=#615 id=615 data-nosnippet>615</a> }
<a href=#616 id=616 data-nosnippet>616</a>
<a href=#617 id=617 data-nosnippet>617</a> <span class="attr">#[test]
<a href=#618 id=618 data-nosnippet>618</a> </span><span class="kw">pub fn </span>test_parse_kill_statement_edge_cases() {
<a href=#619 id=619 data-nosnippet>619</a> <span class="kw">use </span><span class="kw">crate</span>::statements::kill::Kill;
<a href=#620 id=620 data-nosnippet>620</a>
<a href=#621 id=621 data-nosnippet>621</a> <span class="comment">// Test KILL QUERY with zero connection ID
<a href=#622 id=622 data-nosnippet>622</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY 0"</span>;
<a href=#623 id=623 data-nosnippet>623</a> <span class="kw">let </span>statements =
<a href=#624 id=624 data-nosnippet>624</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#625 id=625 data-nosnippet>625</a> .unwrap();
<a href=#626 id=626 data-nosnippet>626</a>
<a href=#627 id=627 data-nosnippet>627</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#628 id=628 data-nosnippet>628</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#629 id=629 data-nosnippet>629</a> Statement::Kill(Kill::ConnectionId(connection_id)) =&gt; {
<a href=#630 id=630 data-nosnippet>630</a> <span class="macro">assert_eq!</span>(<span class="kw-2">*</span>connection_id, <span class="number">0</span>);
<a href=#631 id=631 data-nosnippet>631</a> }
<a href=#632 id=632 data-nosnippet>632</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ConnectionId statement"</span>),
<a href=#633 id=633 data-nosnippet>633</a> }
<a href=#634 id=634 data-nosnippet>634</a>
<a href=#635 id=635 data-nosnippet>635</a> <span class="comment">// Test KILL QUERY with maximum u32 value
<a href=#636 id=636 data-nosnippet>636</a> </span><span class="kw">let </span>sql = <span class="string">"KILL QUERY 4294967295"</span>; <span class="comment">// u32::MAX
<a href=#637 id=637 data-nosnippet>637</a> </span><span class="kw">let </span>statements =
<a href=#638 id=638 data-nosnippet>638</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#639 id=639 data-nosnippet>639</a> .unwrap();
<a href=#640 id=640 data-nosnippet>640</a>
<a href=#641 id=641 data-nosnippet>641</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#642 id=642 data-nosnippet>642</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#643 id=643 data-nosnippet>643</a> Statement::Kill(Kill::ConnectionId(connection_id)) =&gt; {
<a href=#644 id=644 data-nosnippet>644</a> <span class="macro">assert_eq!</span>(<span class="kw-2">*</span>connection_id, <span class="number">4294967295</span>);
<a href=#645 id=645 data-nosnippet>645</a> }
<a href=#646 id=646 data-nosnippet>646</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ConnectionId statement"</span>),
<a href=#647 id=647 data-nosnippet>647</a> }
<a href=#648 id=648 data-nosnippet>648</a>
<a href=#649 id=649 data-nosnippet>649</a> <span class="comment">// Test KILL with empty string process ID
<a href=#650 id=650 data-nosnippet>650</a> </span><span class="kw">let </span>sql = <span class="string">"KILL ''"</span>;
<a href=#651 id=651 data-nosnippet>651</a> <span class="kw">let </span>statements =
<a href=#652 id=652 data-nosnippet>652</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#653 id=653 data-nosnippet>653</a> .unwrap();
<a href=#654 id=654 data-nosnippet>654</a>
<a href=#655 id=655 data-nosnippet>655</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#656 id=656 data-nosnippet>656</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#657 id=657 data-nosnippet>657</a> Statement::Kill(Kill::ProcessId(process_id)) =&gt; {
<a href=#658 id=658 data-nosnippet>658</a> <span class="macro">assert_eq!</span>(process_id, <span class="string">""</span>);
<a href=#659 id=659 data-nosnippet>659</a> }
<a href=#660 id=660 data-nosnippet>660</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ProcessId statement"</span>),
<a href=#661 id=661 data-nosnippet>661</a> }
<a href=#662 id=662 data-nosnippet>662</a> }
<a href=#663 id=663 data-nosnippet>663</a>
<a href=#664 id=664 data-nosnippet>664</a> <span class="attr">#[test]
<a href=#665 id=665 data-nosnippet>665</a> </span><span class="kw">pub fn </span>test_parse_kill_statement_case_insensitive() {
<a href=#666 id=666 data-nosnippet>666</a> <span class="kw">use </span><span class="kw">crate</span>::statements::kill::Kill;
<a href=#667 id=667 data-nosnippet>667</a>
<a href=#668 id=668 data-nosnippet>668</a> <span class="comment">// Test lowercase
<a href=#669 id=669 data-nosnippet>669</a> </span><span class="kw">let </span>sql = <span class="string">"kill query 123"</span>;
<a href=#670 id=670 data-nosnippet>670</a> <span class="kw">let </span>statements =
<a href=#671 id=671 data-nosnippet>671</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#672 id=672 data-nosnippet>672</a> .unwrap();
<a href=#673 id=673 data-nosnippet>673</a>
<a href=#674 id=674 data-nosnippet>674</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#675 id=675 data-nosnippet>675</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#676 id=676 data-nosnippet>676</a> Statement::Kill(Kill::ConnectionId(connection_id)) =&gt; {
<a href=#677 id=677 data-nosnippet>677</a> <span class="macro">assert_eq!</span>(<span class="kw-2">*</span>connection_id, <span class="number">123</span>);
<a href=#678 id=678 data-nosnippet>678</a> }
<a href=#679 id=679 data-nosnippet>679</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ConnectionId statement"</span>),
<a href=#680 id=680 data-nosnippet>680</a> }
<a href=#681 id=681 data-nosnippet>681</a>
<a href=#682 id=682 data-nosnippet>682</a> <span class="comment">// Test mixed case
<a href=#683 id=683 data-nosnippet>683</a> </span><span class="kw">let </span>sql = <span class="string">"Kill Query 456"</span>;
<a href=#684 id=684 data-nosnippet>684</a> <span class="kw">let </span>statements =
<a href=#685 id=685 data-nosnippet>685</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#686 id=686 data-nosnippet>686</a> .unwrap();
<a href=#687 id=687 data-nosnippet>687</a>
<a href=#688 id=688 data-nosnippet>688</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#689 id=689 data-nosnippet>689</a> <span class="kw">match </span><span class="kw-2">&amp;</span>statements[<span class="number">0</span>] {
<a href=#690 id=690 data-nosnippet>690</a> Statement::Kill(Kill::ConnectionId(connection_id)) =&gt; {
<a href=#691 id=691 data-nosnippet>691</a> <span class="macro">assert_eq!</span>(<span class="kw-2">*</span>connection_id, <span class="number">456</span>);
<a href=#692 id=692 data-nosnippet>692</a> }
<a href=#693 id=693 data-nosnippet>693</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"Expected Kill::ConnectionId statement"</span>),
<a href=#694 id=694 data-nosnippet>694</a> }
<a href=#695 id=695 data-nosnippet>695</a> }
<a href=#696 id=696 data-nosnippet>696</a>}
</code></pre></div></section></main></body></html>
+37
View File
@@ -0,0 +1,37 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers.rs`."><title>parsers.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>parsers.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>admin_parser;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">mod </span>alter_parser;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>comment_parser;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>copy_parser;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>create_parser;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>cursor_parser;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>deallocate_parser;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>delete_parser;
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>describe_parser;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>drop_parser;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>error;
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>execute_parser;
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>explain_parser;
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>insert_parser;
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>prepare_parser;
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>query_parser;
<a href=#31 id=31 data-nosnippet>31</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>set_var_parser;
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>show_parser;
<a href=#33 id=33 data-nosnippet>33</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>tql_parser;
<a href=#34 id=34 data-nosnippet>34</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>truncate_parser;
<a href=#35 id=35 data-nosnippet>35</a><span class="kw">pub mod </span>utils;
<a href=#36 id=36 data-nosnippet>36</a><span class="kw">pub mod </span>with_tql_parser;
</code></pre></div></section></main></body></html>
+127
View File
@@ -0,0 +1,127 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/admin_parser.rs`."><title>admin_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>admin_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span><span class="kw">crate</span>::ast::Expr;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="prelude-ty">Result</span>, SyntaxSnafu};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::statements::admin::Admin;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// `admin` extension parser: `admin function(arg1, arg2, ...)`
<a href=#24 id=24 data-nosnippet>24</a>/// or `admin function`
<a href=#25 id=25 data-nosnippet>25</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="doccomment">/// Parse `admin function(arg1, arg2, ...)` or `admin function` statement
<a href=#27 id=27 data-nosnippet>27</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_admin_command(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">let </span>_token = <span class="self">self</span>.parser.next_token();
<a href=#29 id=29 data-nosnippet>29</a>
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">let </span>object_name = <span class="self">self</span>.parser.parse_object_name(<span class="bool-val">false</span>).context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">let </span>func = <span class="kw">match </span><span class="self">self
<a href=#33 id=33 data-nosnippet>33</a> </span>.parser
<a href=#34 id=34 data-nosnippet>34</a> .parse_function(object_name)
<a href=#35 id=35 data-nosnippet>35</a> .context(SyntaxSnafu)<span class="question-mark">?
<a href=#36 id=36 data-nosnippet>36</a> </span>{
<a href=#37 id=37 data-nosnippet>37</a> Expr::Function(f) =&gt; f,
<a href=#38 id=38 data-nosnippet>38</a> <span class="kw">_ </span>=&gt; {
<a href=#39 id=39 data-nosnippet>39</a> <span class="kw">return </span><span class="self">self</span>.unsupported(<span class="self">self</span>.peek_token_as_string());
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a> };
<a href=#42 id=42 data-nosnippet>42</a>
<a href=#43 id=43 data-nosnippet>43</a> <span class="prelude-val">Ok</span>(Statement::Admin(Admin::Func(func)))
<a href=#44 id=44 data-nosnippet>44</a> }
<a href=#45 id=45 data-nosnippet>45</a>}
<a href=#46 id=46 data-nosnippet>46</a>
<a href=#47 id=47 data-nosnippet>47</a><span class="attr">#[cfg(test)]
<a href=#48 id=48 data-nosnippet>48</a></span><span class="kw">mod </span>tests {
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">use </span>sqlparser::ast::{FunctionArguments, ValueWithSpan};
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">use </span><span class="kw">crate</span>::ast::{Expr, Function, FunctionArg, FunctionArgExpr, Value};
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#55 id=55 data-nosnippet>55</a>
<a href=#56 id=56 data-nosnippet>56</a> <span class="attr">#[test]
<a href=#57 id=57 data-nosnippet>57</a> </span><span class="kw">fn </span>test_parse_admin_function() {
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">let </span>sql = <span class="string">"ADMIN flush_table('test')"</span>;
<a href=#59 id=59 data-nosnippet>59</a>
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">let </span><span class="kw-2">mut </span>result =
<a href=#61 id=61 data-nosnippet>61</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#62 id=62 data-nosnippet>62</a> .unwrap();
<a href=#63 id=63 data-nosnippet>63</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">let </span>stmt = result.remove(<span class="number">0</span>);
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmt {
<a href=#66 id=66 data-nosnippet>66</a> Statement::Admin(Admin::Func(Function { name, args, .. })) =&gt; {
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">let </span>FunctionArguments::List(arg_list) = args <span class="kw">else </span>{
<a href=#68 id=68 data-nosnippet>68</a> <span class="macro">unreachable!</span>()
<a href=#69 id=69 data-nosnippet>69</a> };
<a href=#70 id=70 data-nosnippet>70</a> <span class="macro">assert_eq!</span>(<span class="string">"flush_table"</span>, name.to_string());
<a href=#71 id=71 data-nosnippet>71</a> <span class="macro">assert_eq!</span>(arg_list.args.len(), <span class="number">1</span>);
<a href=#72 id=72 data-nosnippet>72</a> <span class="macro">assert!</span>(<span class="macro">matches!</span>(<span class="kw-2">&amp;</span>arg_list.args[<span class="number">0</span>],
<a href=#73 id=73 data-nosnippet>73</a> FunctionArg::Unnamed(FunctionArgExpr::Expr(
<a href=#74 id=74 data-nosnippet>74</a> Expr::Value(ValueWithSpan { value: Value::SingleQuotedString(s), ..})
<a href=#75 id=75 data-nosnippet>75</a> )) <span class="kw">if </span>s == <span class="string">"test"</span>));
<a href=#76 id=76 data-nosnippet>76</a> }
<a href=#77 id=77 data-nosnippet>77</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#78 id=78 data-nosnippet>78</a> }
<a href=#79 id=79 data-nosnippet>79</a>
<a href=#80 id=80 data-nosnippet>80</a> <span class="macro">assert_eq!</span>(sql, stmt.to_string());
<a href=#81 id=81 data-nosnippet>81</a> }
<a href=#82 id=82 data-nosnippet>82</a>
<a href=#83 id=83 data-nosnippet>83</a> <span class="attr">#[test]
<a href=#84 id=84 data-nosnippet>84</a> </span><span class="kw">fn </span>test_parse_admin_function_without_args() {
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">let </span>sql = <span class="string">"ADMIN test()"</span>;
<a href=#86 id=86 data-nosnippet>86</a>
<a href=#87 id=87 data-nosnippet>87</a> <span class="kw">let </span><span class="kw-2">mut </span>result =
<a href=#88 id=88 data-nosnippet>88</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#89 id=89 data-nosnippet>89</a> .unwrap();
<a href=#90 id=90 data-nosnippet>90</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">let </span>stmt = result.remove(<span class="number">0</span>);
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmt {
<a href=#93 id=93 data-nosnippet>93</a> Statement::Admin(Admin::Func(Function { name, args, .. })) =&gt; {
<a href=#94 id=94 data-nosnippet>94</a> <span class="kw">let </span>FunctionArguments::List(arg_list) = args <span class="kw">else </span>{
<a href=#95 id=95 data-nosnippet>95</a> <span class="macro">unreachable!</span>()
<a href=#96 id=96 data-nosnippet>96</a> };
<a href=#97 id=97 data-nosnippet>97</a> <span class="macro">assert_eq!</span>(<span class="string">"test"</span>, name.to_string());
<a href=#98 id=98 data-nosnippet>98</a> <span class="macro">assert_eq!</span>(arg_list.args.len(), <span class="number">0</span>);
<a href=#99 id=99 data-nosnippet>99</a> }
<a href=#100 id=100 data-nosnippet>100</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#101 id=101 data-nosnippet>101</a> }
<a href=#102 id=102 data-nosnippet>102</a>
<a href=#103 id=103 data-nosnippet>103</a> <span class="macro">assert_eq!</span>(<span class="string">"ADMIN test()"</span>, stmt.to_string());
<a href=#104 id=104 data-nosnippet>104</a> }
<a href=#105 id=105 data-nosnippet>105</a>
<a href=#106 id=106 data-nosnippet>106</a> <span class="attr">#[test]
<a href=#107 id=107 data-nosnippet>107</a> </span><span class="kw">fn </span>test_invalid_admin_statement() {
<a href=#108 id=108 data-nosnippet>108</a> <span class="kw">let </span>sql = <span class="string">"ADMIN"</span>;
<a href=#109 id=109 data-nosnippet>109</a> <span class="macro">assert!</span>(
<a href=#110 id=110 data-nosnippet>110</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#111 id=111 data-nosnippet>111</a> .is_err()
<a href=#112 id=112 data-nosnippet>112</a> );
<a href=#113 id=113 data-nosnippet>113</a>
<a href=#114 id=114 data-nosnippet>114</a> <span class="kw">let </span>sql = <span class="string">"ADMIN test"</span>;
<a href=#115 id=115 data-nosnippet>115</a> <span class="macro">assert!</span>(
<a href=#116 id=116 data-nosnippet>116</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#117 id=117 data-nosnippet>117</a> .is_err()
<a href=#118 id=118 data-nosnippet>118</a> );
<a href=#119 id=119 data-nosnippet>119</a>
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">let </span>sql = <span class="string">"ADMIN test test"</span>;
<a href=#121 id=121 data-nosnippet>121</a> <span class="macro">assert!</span>(
<a href=#122 id=122 data-nosnippet>122</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#123 id=123 data-nosnippet>123</a> .is_err()
<a href=#124 id=124 data-nosnippet>124</a> );
<a href=#125 id=125 data-nosnippet>125</a> }
<a href=#126 id=126 data-nosnippet>126</a>}
</code></pre></div></section></main></body></html>
File diff suppressed because it is too large Load Diff
+197
View File
@@ -0,0 +1,197 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/comment_parser.rs`."><title>comment_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>comment_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::ObjectName;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::ast::{Ident, ObjectNamePart};
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, InvalidSqlSnafu, <span class="prelude-ty">Result</span>};
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::parser::{FLOW, ParserContext};
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::statements::comment::{Comment, CommentObject};
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#25 id=25 data-nosnippet>25</a>
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_comment(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token(); <span class="comment">// consume COMMENT
<a href=#29 id=29 data-nosnippet>29</a>
<a href=#30 id=30 data-nosnippet>30</a> </span><span class="kw">if </span>!<span class="self">self</span>.parser.parse_keyword(Keyword::ON) {
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">return </span><span class="self">self</span>.expected(<span class="string">"ON"</span>, <span class="self">self</span>.parser.peek_token());
<a href=#32 id=32 data-nosnippet>32</a> }
<a href=#33 id=33 data-nosnippet>33</a>
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">let </span>target_token = <span class="self">self</span>.parser.next_token();
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">let </span>comment = <span class="kw">match </span>target_token.token {
<a href=#36 id=36 data-nosnippet>36</a> Token::Word(word) <span class="kw">if </span>word.keyword == Keyword::TABLE =&gt; {
<a href=#37 id=37 data-nosnippet>37</a> <span class="kw">let </span>raw_table =
<a href=#38 id=38 data-nosnippet>38</a> <span class="self">self</span>.parse_object_name()
<a href=#39 id=39 data-nosnippet>39</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#40 id=40 data-nosnippet>40</a> expected: <span class="string">"a table name"</span>,
<a href=#41 id=41 data-nosnippet>41</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#42 id=42 data-nosnippet>42</a> })<span class="question-mark">?</span>;
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw">let </span>table = <span class="self">Self</span>::canonicalize_object_name(raw_table)<span class="question-mark">?</span>;
<a href=#44 id=44 data-nosnippet>44</a> CommentObject::Table(table)
<a href=#45 id=45 data-nosnippet>45</a> }
<a href=#46 id=46 data-nosnippet>46</a> Token::Word(word) <span class="kw">if </span>word.keyword == Keyword::COLUMN =&gt; {
<a href=#47 id=47 data-nosnippet>47</a> <span class="self">self</span>.parse_column_comment_target()<span class="question-mark">?
<a href=#48 id=48 data-nosnippet>48</a> </span>}
<a href=#49 id=49 data-nosnippet>49</a> Token::Word(word)
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">if </span>word.keyword == Keyword::NoKeyword &amp;&amp; word.value.eq_ignore_ascii_case(FLOW) =&gt;
<a href=#51 id=51 data-nosnippet>51</a> {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">let </span>raw_flow =
<a href=#53 id=53 data-nosnippet>53</a> <span class="self">self</span>.parse_object_name()
<a href=#54 id=54 data-nosnippet>54</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#55 id=55 data-nosnippet>55</a> expected: <span class="string">"a flow name"</span>,
<a href=#56 id=56 data-nosnippet>56</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#57 id=57 data-nosnippet>57</a> })<span class="question-mark">?</span>;
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">let </span>flow = <span class="self">Self</span>::canonicalize_object_name(raw_flow)<span class="question-mark">?</span>;
<a href=#59 id=59 data-nosnippet>59</a> CommentObject::Flow(flow)
<a href=#60 id=60 data-nosnippet>60</a> }
<a href=#61 id=61 data-nosnippet>61</a> <span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="self">self</span>.expected(<span class="string">"TABLE, COLUMN or FLOW"</span>, target_token),
<a href=#62 id=62 data-nosnippet>62</a> };
<a href=#63 id=63 data-nosnippet>63</a>
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">if </span>!<span class="self">self</span>.parser.parse_keyword(Keyword::IS) {
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">return </span><span class="self">self</span>.expected(<span class="string">"IS"</span>, <span class="self">self</span>.parser.peek_token());
<a href=#66 id=66 data-nosnippet>66</a> }
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a> <span class="kw">let </span>comment_value = <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::NULL) {
<a href=#69 id=69 data-nosnippet>69</a> <span class="prelude-val">None
<a href=#70 id=70 data-nosnippet>70</a> </span>} <span class="kw">else </span>{
<a href=#71 id=71 data-nosnippet>71</a> <span class="prelude-val">Some</span>(
<a href=#72 id=72 data-nosnippet>72</a> <span class="self">self</span>.parser
<a href=#73 id=73 data-nosnippet>73</a> .parse_literal_string()
<a href=#74 id=74 data-nosnippet>74</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>,
<a href=#75 id=75 data-nosnippet>75</a> )
<a href=#76 id=76 data-nosnippet>76</a> };
<a href=#77 id=77 data-nosnippet>77</a>
<a href=#78 id=78 data-nosnippet>78</a> <span class="prelude-val">Ok</span>(Statement::Comment(Comment {
<a href=#79 id=79 data-nosnippet>79</a> object: comment,
<a href=#80 id=80 data-nosnippet>80</a> comment: comment_value,
<a href=#81 id=81 data-nosnippet>81</a> }))
<a href=#82 id=82 data-nosnippet>82</a> }
<a href=#83 id=83 data-nosnippet>83</a>
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw">fn </span>parse_column_comment_target(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;CommentObject&gt; {
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">let </span>raw = <span class="self">self
<a href=#86 id=86 data-nosnippet>86</a> </span>.parse_object_name()
<a href=#87 id=87 data-nosnippet>87</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#88 id=88 data-nosnippet>88</a> expected: <span class="string">"a column reference"</span>,
<a href=#89 id=89 data-nosnippet>89</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#90 id=90 data-nosnippet>90</a> })<span class="question-mark">?</span>;
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">let </span>canonical = <span class="self">Self</span>::canonicalize_object_name(raw)<span class="question-mark">?</span>;
<a href=#92 id=92 data-nosnippet>92</a>
<a href=#93 id=93 data-nosnippet>93</a> <span class="kw">let </span><span class="kw-2">mut </span>parts = canonical.<span class="number">0</span>;
<a href=#94 id=94 data-nosnippet>94</a> <span class="macro">ensure!</span>(
<a href=#95 id=95 data-nosnippet>95</a> parts.len() &gt;= <span class="number">2</span>,
<a href=#96 id=96 data-nosnippet>96</a> InvalidSqlSnafu {
<a href=#97 id=97 data-nosnippet>97</a> msg: <span class="string">"COMMENT ON COLUMN expects &lt;table&gt;.&lt;column&gt;"</span>.to_string(),
<a href=#98 id=98 data-nosnippet>98</a> }
<a href=#99 id=99 data-nosnippet>99</a> );
<a href=#100 id=100 data-nosnippet>100</a>
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">let </span>column_part = parts.pop().unwrap();
<a href=#102 id=102 data-nosnippet>102</a> <span class="kw">let </span>ObjectNamePart::Identifier(column_ident) = column_part <span class="kw">else </span>{
<a href=#103 id=103 data-nosnippet>103</a> <span class="macro">unreachable!</span>(<span class="string">"canonicalized object name should only contain identifiers"</span>);
<a href=#104 id=104 data-nosnippet>104</a> };
<a href=#105 id=105 data-nosnippet>105</a>
<a href=#106 id=106 data-nosnippet>106</a> <span class="kw">let </span>column = ParserContext::canonicalize_identifier(column_ident);
<a href=#107 id=107 data-nosnippet>107</a>
<a href=#108 id=108 data-nosnippet>108</a> <span class="kw">let </span><span class="kw-2">mut </span>table_idents: Vec&lt;Ident&gt; = Vec::with_capacity(parts.len());
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw">for </span>part <span class="kw">in </span>parts {
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">match </span>part {
<a href=#111 id=111 data-nosnippet>111</a> ObjectNamePart::Identifier(ident) =&gt; table_idents.push(ident),
<a href=#112 id=112 data-nosnippet>112</a> ObjectNamePart::Function(<span class="kw">_</span>) =&gt; {
<a href=#113 id=113 data-nosnippet>113</a> <span class="macro">unreachable!</span>(<span class="string">"canonicalized object name should only contain identifiers"</span>)
<a href=#114 id=114 data-nosnippet>114</a> }
<a href=#115 id=115 data-nosnippet>115</a> }
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a>
<a href=#118 id=118 data-nosnippet>118</a> <span class="macro">ensure!</span>(
<a href=#119 id=119 data-nosnippet>119</a> !table_idents.is_empty(),
<a href=#120 id=120 data-nosnippet>120</a> InvalidSqlSnafu {
<a href=#121 id=121 data-nosnippet>121</a> msg: <span class="string">"Table name is required before column name"</span>.to_string(),
<a href=#122 id=122 data-nosnippet>122</a> }
<a href=#123 id=123 data-nosnippet>123</a> );
<a href=#124 id=124 data-nosnippet>124</a>
<a href=#125 id=125 data-nosnippet>125</a> <span class="kw">let </span>table = ObjectName::from(table_idents);
<a href=#126 id=126 data-nosnippet>126</a>
<a href=#127 id=127 data-nosnippet>127</a> <span class="prelude-val">Ok</span>(CommentObject::Column { table, column })
<a href=#128 id=128 data-nosnippet>128</a> }
<a href=#129 id=129 data-nosnippet>129</a>}
<a href=#130 id=130 data-nosnippet>130</a>
<a href=#131 id=131 data-nosnippet>131</a><span class="attr">#[cfg(test)]
<a href=#132 id=132 data-nosnippet>132</a></span><span class="kw">mod </span>tests {
<a href=#133 id=133 data-nosnippet>133</a> <span class="kw">use </span>std::assert_matches;
<a href=#134 id=134 data-nosnippet>134</a>
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#136 id=136 data-nosnippet>136</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#137 id=137 data-nosnippet>137</a> <span class="kw">use </span><span class="kw">crate</span>::statements::comment::CommentObject;
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#139 id=139 data-nosnippet>139</a>
<a href=#140 id=140 data-nosnippet>140</a> <span class="kw">fn </span>parse(sql: <span class="kw-2">&amp;</span>str) -&gt; Statement {
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#142 id=142 data-nosnippet>142</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#143 id=143 data-nosnippet>143</a> .unwrap();
<a href=#144 id=144 data-nosnippet>144</a> <span class="macro">assert_eq!</span>(stmts.len(), <span class="number">1</span>);
<a href=#145 id=145 data-nosnippet>145</a> stmts.pop().unwrap()
<a href=#146 id=146 data-nosnippet>146</a> }
<a href=#147 id=147 data-nosnippet>147</a>
<a href=#148 id=148 data-nosnippet>148</a> <span class="attr">#[test]
<a href=#149 id=149 data-nosnippet>149</a> </span><span class="kw">fn </span>test_parse_comment_on_table() {
<a href=#150 id=150 data-nosnippet>150</a> <span class="kw">let </span>stmt = parse(<span class="string">"COMMENT ON TABLE mytable IS 'test';"</span>);
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw">match </span>stmt {
<a href=#152 id=152 data-nosnippet>152</a> Statement::Comment(comment) =&gt; {
<a href=#153 id=153 data-nosnippet>153</a> <span class="macro">assert_matches!</span>(comment.object, CommentObject::Table(<span class="kw-2">ref </span>name) <span class="kw">if </span>name.to_string() == <span class="string">"mytable"</span>);
<a href=#154 id=154 data-nosnippet>154</a> <span class="macro">assert_eq!</span>(comment.comment.as_deref(), <span class="prelude-val">Some</span>(<span class="string">"test"</span>));
<a href=#155 id=155 data-nosnippet>155</a> }
<a href=#156 id=156 data-nosnippet>156</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"expected comment statement"</span>),
<a href=#157 id=157 data-nosnippet>157</a> }
<a href=#158 id=158 data-nosnippet>158</a>
<a href=#159 id=159 data-nosnippet>159</a> <span class="kw">let </span>stmt = parse(<span class="string">"COMMENT ON TABLE mytable IS NULL;"</span>);
<a href=#160 id=160 data-nosnippet>160</a> <span class="kw">match </span>stmt {
<a href=#161 id=161 data-nosnippet>161</a> Statement::Comment(comment) =&gt; {
<a href=#162 id=162 data-nosnippet>162</a> <span class="macro">assert_matches!</span>(comment.object, CommentObject::Table(<span class="kw-2">ref </span>name) <span class="kw">if </span>name.to_string() == <span class="string">"mytable"</span>);
<a href=#163 id=163 data-nosnippet>163</a> <span class="macro">assert!</span>(comment.comment.is_none());
<a href=#164 id=164 data-nosnippet>164</a> }
<a href=#165 id=165 data-nosnippet>165</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"expected comment statement"</span>),
<a href=#166 id=166 data-nosnippet>166</a> }
<a href=#167 id=167 data-nosnippet>167</a> }
<a href=#168 id=168 data-nosnippet>168</a>
<a href=#169 id=169 data-nosnippet>169</a> <span class="attr">#[test]
<a href=#170 id=170 data-nosnippet>170</a> </span><span class="kw">fn </span>test_parse_comment_on_column() {
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">let </span>stmt = parse(<span class="string">"COMMENT ON COLUMN my_schema.my_table.my_col IS 'desc';"</span>);
<a href=#172 id=172 data-nosnippet>172</a> <span class="kw">match </span>stmt {
<a href=#173 id=173 data-nosnippet>173</a> Statement::Comment(comment) =&gt; <span class="kw">match </span>comment.object {
<a href=#174 id=174 data-nosnippet>174</a> CommentObject::Column { table, column } =&gt; {
<a href=#175 id=175 data-nosnippet>175</a> <span class="macro">assert_eq!</span>(table.to_string(), <span class="string">"my_schema.my_table"</span>);
<a href=#176 id=176 data-nosnippet>176</a> <span class="macro">assert_eq!</span>(column.value, <span class="string">"my_col"</span>);
<a href=#177 id=177 data-nosnippet>177</a> <span class="macro">assert_eq!</span>(comment.comment.as_deref(), <span class="prelude-val">Some</span>(<span class="string">"desc"</span>));
<a href=#178 id=178 data-nosnippet>178</a> }
<a href=#179 id=179 data-nosnippet>179</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"expected column comment"</span>),
<a href=#180 id=180 data-nosnippet>180</a> },
<a href=#181 id=181 data-nosnippet>181</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"expected comment statement"</span>),
<a href=#182 id=182 data-nosnippet>182</a> }
<a href=#183 id=183 data-nosnippet>183</a> }
<a href=#184 id=184 data-nosnippet>184</a>
<a href=#185 id=185 data-nosnippet>185</a> <span class="attr">#[test]
<a href=#186 id=186 data-nosnippet>186</a> </span><span class="kw">fn </span>test_parse_comment_on_flow() {
<a href=#187 id=187 data-nosnippet>187</a> <span class="kw">let </span>stmt = parse(<span class="string">"COMMENT ON FLOW my_flow IS 'desc';"</span>);
<a href=#188 id=188 data-nosnippet>188</a> <span class="kw">match </span>stmt {
<a href=#189 id=189 data-nosnippet>189</a> Statement::Comment(comment) =&gt; {
<a href=#190 id=190 data-nosnippet>190</a> <span class="macro">assert_matches!</span>(comment.object, CommentObject::Flow(<span class="kw-2">ref </span>name) <span class="kw">if </span>name.to_string() == <span class="string">"my_flow"</span>);
<a href=#191 id=191 data-nosnippet>191</a> <span class="macro">assert_eq!</span>(comment.comment.as_deref(), <span class="prelude-val">Some</span>(<span class="string">"desc"</span>));
<a href=#192 id=192 data-nosnippet>192</a> }
<a href=#193 id=193 data-nosnippet>193</a> <span class="kw">_ </span>=&gt; <span class="macro">panic!</span>(<span class="string">"expected comment statement"</span>),
<a href=#194 id=194 data-nosnippet>194</a> }
<a href=#195 id=195 data-nosnippet>195</a> }
<a href=#196 id=196 data-nosnippet>196</a>}
</code></pre></div></section></main></body></html>
+858
View File
@@ -0,0 +1,858 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/copy_parser.rs`."><title>copy_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>copy_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::tokenizer::Token::Word;
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::statements::OptionMap;
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::statements::copy::{
<a href=#24 id=24 data-nosnippet>24</a> CopyDatabase, CopyDatabaseArgument, CopyQueryTo, CopyQueryToArgument, CopyTable,
<a href=#25 id=25 data-nosnippet>25</a> CopyTableArgument,
<a href=#26 id=26 data-nosnippet>26</a>};
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">use </span><span class="kw">crate</span>::util::parse_option_string;
<a href=#29 id=29 data-nosnippet>29</a>
<a href=#30 id=30 data-nosnippet>30</a><span class="comment">// COPY tbl TO 'output.parquet';
<a href=#31 id=31 data-nosnippet>31</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_copy(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">let </span>next = <span class="self">self</span>.parser.peek_token();
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">if </span>next.token == Token::LParen {
<a href=#36 id=36 data-nosnippet>36</a> <span class="kw">let </span>copy_query = <span class="self">self</span>.parse_copy_query_to()<span class="question-mark">?</span>;
<a href=#37 id=37 data-nosnippet>37</a> <span class="comment">// the COPY ... TO STDOUT is a special case for postgres wire protocol
<a href=#38 id=38 data-nosnippet>38</a> // the logic is completely identical to query, but with an alternative data encoding on transport
<a href=#39 id=39 data-nosnippet>39</a> //
<a href=#40 id=40 data-nosnippet>40</a> // so at the query engine level, we simple parse the command as it's inner query
<a href=#41 id=41 data-nosnippet>41</a> // we will deal with the encoding and its format options in server/src/postgres/handler.rs
<a href=#42 id=42 data-nosnippet>42</a> </span><span class="kw">if </span>copy_query.arg.location == <span class="string">"STDOUT" </span>{
<a href=#43 id=43 data-nosnippet>43</a> <span class="prelude-val">Ok</span>(<span class="kw-2">*</span>copy_query.query)
<a href=#44 id=44 data-nosnippet>44</a> } <span class="kw">else </span>{
<a href=#45 id=45 data-nosnippet>45</a> <span class="prelude-val">Ok</span>(Statement::Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyQueryTo(
<a href=#46 id=46 data-nosnippet>46</a> copy_query,
<a href=#47 id=47 data-nosnippet>47</a> )))
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a> } <span class="kw">else if let </span>Word(word) = next.token
<a href=#50 id=50 data-nosnippet>50</a> &amp;&amp; word.keyword == Keyword::DATABASE
<a href=#51 id=51 data-nosnippet>51</a> {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">let </span>copy_database = <span class="self">self</span>.parser_copy_database()<span class="question-mark">?</span>;
<a href=#54 id=54 data-nosnippet>54</a> <span class="prelude-val">Ok</span>(Statement::Copy(
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">crate</span>::statements::copy::Copy::CopyDatabase(copy_database),
<a href=#56 id=56 data-nosnippet>56</a> ))
<a href=#57 id=57 data-nosnippet>57</a> } <span class="kw">else </span>{
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">let </span>copy_table = <span class="self">self</span>.parse_copy_table()<span class="question-mark">?</span>;
<a href=#59 id=59 data-nosnippet>59</a> <span class="prelude-val">Ok</span>(Statement::Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyTable(
<a href=#60 id=60 data-nosnippet>60</a> copy_table,
<a href=#61 id=61 data-nosnippet>61</a> )))
<a href=#62 id=62 data-nosnippet>62</a> }
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a>
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">fn </span>parser_copy_database(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;CopyDatabase&gt; {
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">let </span>database_name = <span class="self">self
<a href=#67 id=67 data-nosnippet>67</a> </span>.parse_object_name()
<a href=#68 id=68 data-nosnippet>68</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#69 id=69 data-nosnippet>69</a> expected: <span class="string">"a database name"</span>,
<a href=#70 id=70 data-nosnippet>70</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#71 id=71 data-nosnippet>71</a> })<span class="question-mark">?</span>;
<a href=#72 id=72 data-nosnippet>72</a>
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">let </span>req = <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::TO) {
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">let </span>(with, connection, location, limit) = <span class="self">self</span>.parse_copy_parameters()<span class="question-mark">?</span>;
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">if </span>limit.is_some() {
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw">return </span>error::InvalidSqlSnafu {
<a href=#77 id=77 data-nosnippet>77</a> msg: <span class="string">"limit is not supported"</span>,
<a href=#78 id=78 data-nosnippet>78</a> }
<a href=#79 id=79 data-nosnippet>79</a> .fail();
<a href=#80 id=80 data-nosnippet>80</a> }
<a href=#81 id=81 data-nosnippet>81</a>
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">let </span>argument = CopyDatabaseArgument {
<a href=#83 id=83 data-nosnippet>83</a> database_name,
<a href=#84 id=84 data-nosnippet>84</a> with,
<a href=#85 id=85 data-nosnippet>85</a> connection,
<a href=#86 id=86 data-nosnippet>86</a> location,
<a href=#87 id=87 data-nosnippet>87</a> };
<a href=#88 id=88 data-nosnippet>88</a> CopyDatabase::To(argument)
<a href=#89 id=89 data-nosnippet>89</a> } <span class="kw">else </span>{
<a href=#90 id=90 data-nosnippet>90</a> <span class="self">self</span>.parser
<a href=#91 id=91 data-nosnippet>91</a> .expect_keyword(Keyword::FROM)
<a href=#92 id=92 data-nosnippet>92</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#93 id=93 data-nosnippet>93</a> <span class="kw">let </span>(with, connection, location, limit) = <span class="self">self</span>.parse_copy_parameters()<span class="question-mark">?</span>;
<a href=#94 id=94 data-nosnippet>94</a> <span class="kw">if </span>limit.is_some() {
<a href=#95 id=95 data-nosnippet>95</a> <span class="kw">return </span>error::InvalidSqlSnafu {
<a href=#96 id=96 data-nosnippet>96</a> msg: <span class="string">"limit is not supported"</span>,
<a href=#97 id=97 data-nosnippet>97</a> }
<a href=#98 id=98 data-nosnippet>98</a> .fail();
<a href=#99 id=99 data-nosnippet>99</a> }
<a href=#100 id=100 data-nosnippet>100</a>
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">let </span>argument = CopyDatabaseArgument {
<a href=#102 id=102 data-nosnippet>102</a> database_name,
<a href=#103 id=103 data-nosnippet>103</a> with,
<a href=#104 id=104 data-nosnippet>104</a> connection,
<a href=#105 id=105 data-nosnippet>105</a> location,
<a href=#106 id=106 data-nosnippet>106</a> };
<a href=#107 id=107 data-nosnippet>107</a> CopyDatabase::From(argument)
<a href=#108 id=108 data-nosnippet>108</a> };
<a href=#109 id=109 data-nosnippet>109</a> <span class="prelude-val">Ok</span>(req)
<a href=#110 id=110 data-nosnippet>110</a> }
<a href=#111 id=111 data-nosnippet>111</a>
<a href=#112 id=112 data-nosnippet>112</a> <span class="kw">fn </span>parse_copy_table(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;CopyTable&gt; {
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">let </span>raw_table_name = <span class="self">self
<a href=#114 id=114 data-nosnippet>114</a> </span>.parse_object_name()
<a href=#115 id=115 data-nosnippet>115</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#116 id=116 data-nosnippet>116</a> expected: <span class="string">"a table name"</span>,
<a href=#117 id=117 data-nosnippet>117</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#118 id=118 data-nosnippet>118</a> })<span class="question-mark">?</span>;
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">let </span>table_name = <span class="self">Self</span>::canonicalize_object_name(raw_table_name)<span class="question-mark">?</span>;
<a href=#120 id=120 data-nosnippet>120</a>
<a href=#121 id=121 data-nosnippet>121</a> <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::TO) {
<a href=#122 id=122 data-nosnippet>122</a> <span class="kw">let </span>(with, connection, location, limit) = <span class="self">self</span>.parse_copy_parameters()<span class="question-mark">?</span>;
<a href=#123 id=123 data-nosnippet>123</a> <span class="prelude-val">Ok</span>(CopyTable::To(CopyTableArgument {
<a href=#124 id=124 data-nosnippet>124</a> table_name,
<a href=#125 id=125 data-nosnippet>125</a> with,
<a href=#126 id=126 data-nosnippet>126</a> connection,
<a href=#127 id=127 data-nosnippet>127</a> location,
<a href=#128 id=128 data-nosnippet>128</a> limit,
<a href=#129 id=129 data-nosnippet>129</a> }))
<a href=#130 id=130 data-nosnippet>130</a> } <span class="kw">else </span>{
<a href=#131 id=131 data-nosnippet>131</a> <span class="self">self</span>.parser
<a href=#132 id=132 data-nosnippet>132</a> .expect_keyword(Keyword::FROM)
<a href=#133 id=133 data-nosnippet>133</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#134 id=134 data-nosnippet>134</a> <span class="kw">let </span>(with, connection, location, limit) = <span class="self">self</span>.parse_copy_parameters()<span class="question-mark">?</span>;
<a href=#135 id=135 data-nosnippet>135</a> <span class="prelude-val">Ok</span>(CopyTable::From(CopyTableArgument {
<a href=#136 id=136 data-nosnippet>136</a> table_name,
<a href=#137 id=137 data-nosnippet>137</a> with,
<a href=#138 id=138 data-nosnippet>138</a> connection,
<a href=#139 id=139 data-nosnippet>139</a> location,
<a href=#140 id=140 data-nosnippet>140</a> limit,
<a href=#141 id=141 data-nosnippet>141</a> }))
<a href=#142 id=142 data-nosnippet>142</a> }
<a href=#143 id=143 data-nosnippet>143</a> }
<a href=#144 id=144 data-nosnippet>144</a>
<a href=#145 id=145 data-nosnippet>145</a> <span class="kw">fn </span>parse_copy_query_to(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;CopyQueryTo&gt; {
<a href=#146 id=146 data-nosnippet>146</a> <span class="self">self</span>.parser
<a href=#147 id=147 data-nosnippet>147</a> .expect_token(<span class="kw-2">&amp;</span>Token::LParen)
<a href=#148 id=148 data-nosnippet>148</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#149 id=149 data-nosnippet>149</a> expected: <span class="string">"'('"</span>,
<a href=#150 id=150 data-nosnippet>150</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#151 id=151 data-nosnippet>151</a> })<span class="question-mark">?</span>;
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">let </span>query = <span class="self">self</span>.parse_query()<span class="question-mark">?</span>;
<a href=#153 id=153 data-nosnippet>153</a> <span class="self">self</span>.parser
<a href=#154 id=154 data-nosnippet>154</a> .expect_token(<span class="kw-2">&amp;</span>Token::RParen)
<a href=#155 id=155 data-nosnippet>155</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#156 id=156 data-nosnippet>156</a> expected: <span class="string">"')'"</span>,
<a href=#157 id=157 data-nosnippet>157</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#158 id=158 data-nosnippet>158</a> })<span class="question-mark">?</span>;
<a href=#159 id=159 data-nosnippet>159</a> <span class="self">self</span>.parser
<a href=#160 id=160 data-nosnippet>160</a> .expect_keyword(Keyword::TO)
<a href=#161 id=161 data-nosnippet>161</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#162 id=162 data-nosnippet>162</a>
<a href=#163 id=163 data-nosnippet>163</a> <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::STDOUT) {
<a href=#164 id=164 data-nosnippet>164</a> <span class="comment">// early return without parsing options
<a href=#165 id=165 data-nosnippet>165</a> // we will deal with copy to stdout on postgres protocol layer
<a href=#166 id=166 data-nosnippet>166</a> // consume [WITH] (...) options if present (they will be ignored)
<a href=#167 id=167 data-nosnippet>167</a> // we support both "WITH (FORMAT binary)" and "(FORMAT binary)"
<a href=#168 id=168 data-nosnippet>168</a> // for PostgreSQL compatibility
<a href=#169 id=169 data-nosnippet>169</a>
<a href=#170 id=170 data-nosnippet>170</a> // Check for optional WITH keyword or direct LParen (PostgreSQL syntax)
<a href=#171 id=171 data-nosnippet>171</a> // Both "WITH (...)" and "(...)" are valid after STDOUT
<a href=#172 id=172 data-nosnippet>172</a> </span><span class="kw">let _ </span>= <span class="self">self</span>.parser.parse_keyword(Keyword::WITH);
<a href=#173 id=173 data-nosnippet>173</a> <span class="kw">if </span><span class="self">self</span>.parser.peek_token().token == Token::LParen {
<a href=#174 id=174 data-nosnippet>174</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#175 id=175 data-nosnippet>175</a> <span class="comment">// consume all tokens until we find matching RParen
<a href=#176 id=176 data-nosnippet>176</a> </span><span class="kw">let </span><span class="kw-2">mut </span>depth = <span class="number">1</span>;
<a href=#177 id=177 data-nosnippet>177</a> <span class="kw">while </span>depth &gt; <span class="number">0 </span>{
<a href=#178 id=178 data-nosnippet>178</a> <span class="kw">match </span><span class="self">self</span>.parser.next_token().token {
<a href=#179 id=179 data-nosnippet>179</a> Token::LParen =&gt; depth += <span class="number">1</span>,
<a href=#180 id=180 data-nosnippet>180</a> Token::RParen =&gt; depth -= <span class="number">1</span>,
<a href=#181 id=181 data-nosnippet>181</a> Token::EOF =&gt; {
<a href=#182 id=182 data-nosnippet>182</a> <span class="kw">return </span>error::UnexpectedTokenSnafu {
<a href=#183 id=183 data-nosnippet>183</a> expected: <span class="string">")"</span>,
<a href=#184 id=184 data-nosnippet>184</a> actual: <span class="string">"EOF"</span>,
<a href=#185 id=185 data-nosnippet>185</a> }
<a href=#186 id=186 data-nosnippet>186</a> .fail();
<a href=#187 id=187 data-nosnippet>187</a> }
<a href=#188 id=188 data-nosnippet>188</a> <span class="kw">_ </span>=&gt; {}
<a href=#189 id=189 data-nosnippet>189</a> }
<a href=#190 id=190 data-nosnippet>190</a> }
<a href=#191 id=191 data-nosnippet>191</a> }
<a href=#192 id=192 data-nosnippet>192</a>
<a href=#193 id=193 data-nosnippet>193</a> <span class="prelude-val">Ok</span>(CopyQueryTo {
<a href=#194 id=194 data-nosnippet>194</a> query: Box::new(query),
<a href=#195 id=195 data-nosnippet>195</a> arg: CopyQueryToArgument {
<a href=#196 id=196 data-nosnippet>196</a> with: OptionMap::default(),
<a href=#197 id=197 data-nosnippet>197</a> connection: OptionMap::default(),
<a href=#198 id=198 data-nosnippet>198</a> location: <span class="string">"STDOUT"</span>.to_string(),
<a href=#199 id=199 data-nosnippet>199</a> },
<a href=#200 id=200 data-nosnippet>200</a> })
<a href=#201 id=201 data-nosnippet>201</a> } <span class="kw">else </span>{
<a href=#202 id=202 data-nosnippet>202</a> <span class="kw">let </span>(with, connection, location, limit) = <span class="self">self</span>.parse_copy_parameters()<span class="question-mark">?</span>;
<a href=#203 id=203 data-nosnippet>203</a> <span class="kw">if </span>limit.is_some() {
<a href=#204 id=204 data-nosnippet>204</a> <span class="kw">return </span>error::InvalidSqlSnafu {
<a href=#205 id=205 data-nosnippet>205</a> msg: <span class="string">"limit is not supported"</span>,
<a href=#206 id=206 data-nosnippet>206</a> }
<a href=#207 id=207 data-nosnippet>207</a> .fail();
<a href=#208 id=208 data-nosnippet>208</a> }
<a href=#209 id=209 data-nosnippet>209</a> <span class="prelude-val">Ok</span>(CopyQueryTo {
<a href=#210 id=210 data-nosnippet>210</a> query: Box::new(query),
<a href=#211 id=211 data-nosnippet>211</a> arg: CopyQueryToArgument {
<a href=#212 id=212 data-nosnippet>212</a> with,
<a href=#213 id=213 data-nosnippet>213</a> connection,
<a href=#214 id=214 data-nosnippet>214</a> location,
<a href=#215 id=215 data-nosnippet>215</a> },
<a href=#216 id=216 data-nosnippet>216</a> })
<a href=#217 id=217 data-nosnippet>217</a> }
<a href=#218 id=218 data-nosnippet>218</a> }
<a href=#219 id=219 data-nosnippet>219</a>
<a href=#220 id=220 data-nosnippet>220</a> <span class="kw">fn </span>parse_copy_parameters(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;(OptionMap, OptionMap, String, <span class="prelude-ty">Option</span>&lt;u64&gt;)&gt; {
<a href=#221 id=221 data-nosnippet>221</a> <span class="kw">let </span>location =
<a href=#222 id=222 data-nosnippet>222</a> <span class="self">self</span>.parser
<a href=#223 id=223 data-nosnippet>223</a> .parse_literal_string()
<a href=#224 id=224 data-nosnippet>224</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#225 id=225 data-nosnippet>225</a> expected: <span class="string">"a file name"</span>,
<a href=#226 id=226 data-nosnippet>226</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#227 id=227 data-nosnippet>227</a> })<span class="question-mark">?</span>;
<a href=#228 id=228 data-nosnippet>228</a>
<a href=#229 id=229 data-nosnippet>229</a> <span class="kw">let </span>options = <span class="self">self
<a href=#230 id=230 data-nosnippet>230</a> </span>.parser
<a href=#231 id=231 data-nosnippet>231</a> .parse_options(Keyword::WITH)
<a href=#232 id=232 data-nosnippet>232</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#233 id=233 data-nosnippet>233</a>
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">let </span>with = options
<a href=#235 id=235 data-nosnippet>235</a> .into_iter()
<a href=#236 id=236 data-nosnippet>236</a> .map(parse_option_string)
<a href=#237 id=237 data-nosnippet>237</a> .collect::&lt;<span class="prelude-ty">Result</span>&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;&gt;()<span class="question-mark">?</span>;
<a href=#238 id=238 data-nosnippet>238</a> <span class="kw">let </span>with = OptionMap::new(with);
<a href=#239 id=239 data-nosnippet>239</a>
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">let </span>connection_options = <span class="self">self
<a href=#241 id=241 data-nosnippet>241</a> </span>.parser
<a href=#242 id=242 data-nosnippet>242</a> .parse_options(Keyword::CONNECTION)
<a href=#243 id=243 data-nosnippet>243</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#244 id=244 data-nosnippet>244</a>
<a href=#245 id=245 data-nosnippet>245</a> <span class="kw">let </span>connection = connection_options
<a href=#246 id=246 data-nosnippet>246</a> .into_iter()
<a href=#247 id=247 data-nosnippet>247</a> .map(parse_option_string)
<a href=#248 id=248 data-nosnippet>248</a> .collect::&lt;<span class="prelude-ty">Result</span>&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;&gt;()<span class="question-mark">?</span>;
<a href=#249 id=249 data-nosnippet>249</a> <span class="kw">let </span>connection = OptionMap::new(connection);
<a href=#250 id=250 data-nosnippet>250</a>
<a href=#251 id=251 data-nosnippet>251</a> <span class="kw">let </span>limit = <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::LIMIT) {
<a href=#252 id=252 data-nosnippet>252</a> <span class="prelude-val">Some</span>(
<a href=#253 id=253 data-nosnippet>253</a> <span class="self">self</span>.parser
<a href=#254 id=254 data-nosnippet>254</a> .parse_literal_uint()
<a href=#255 id=255 data-nosnippet>255</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#256 id=256 data-nosnippet>256</a> expected: <span class="string">"the number of maximum rows"</span>,
<a href=#257 id=257 data-nosnippet>257</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#258 id=258 data-nosnippet>258</a> })<span class="question-mark">?</span>,
<a href=#259 id=259 data-nosnippet>259</a> )
<a href=#260 id=260 data-nosnippet>260</a> } <span class="kw">else </span>{
<a href=#261 id=261 data-nosnippet>261</a> <span class="prelude-val">None
<a href=#262 id=262 data-nosnippet>262</a> </span>};
<a href=#263 id=263 data-nosnippet>263</a>
<a href=#264 id=264 data-nosnippet>264</a> <span class="prelude-val">Ok</span>((with, connection, location, limit))
<a href=#265 id=265 data-nosnippet>265</a> }
<a href=#266 id=266 data-nosnippet>266</a>}
<a href=#267 id=267 data-nosnippet>267</a>
<a href=#268 id=268 data-nosnippet>268</a><span class="attr">#[cfg(test)]
<a href=#269 id=269 data-nosnippet>269</a></span><span class="kw">mod </span>tests {
<a href=#270 id=270 data-nosnippet>270</a> <span class="kw">use </span>std::assert_matches;
<a href=#271 id=271 data-nosnippet>271</a> <span class="kw">use </span>std::collections::HashMap;
<a href=#272 id=272 data-nosnippet>272</a>
<a href=#273 id=273 data-nosnippet>273</a> <span class="kw">use </span>sqlparser::ast::{Ident, ObjectName};
<a href=#274 id=274 data-nosnippet>274</a>
<a href=#275 id=275 data-nosnippet>275</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#276 id=276 data-nosnippet>276</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#277 id=277 data-nosnippet>277</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement::Copy;
<a href=#279 id=279 data-nosnippet>279</a>
<a href=#280 id=280 data-nosnippet>280</a> <span class="attr">#[test]
<a href=#281 id=281 data-nosnippet>281</a> </span><span class="kw">fn </span>test_parse_copy_table() {
<a href=#282 id=282 data-nosnippet>282</a> <span class="kw">let </span>sql0 = <span class="string">"COPY catalog0.schema0.tbl TO 'tbl_file.parquet'"</span>;
<a href=#283 id=283 data-nosnippet>283</a> <span class="kw">let </span>sql1 = <span class="string">"COPY catalog0.schema0.tbl TO 'tbl_file.parquet' WITH (FORMAT = 'parquet')"</span>;
<a href=#284 id=284 data-nosnippet>284</a> <span class="kw">let </span>result0 = ParserContext::create_with_dialect(
<a href=#285 id=285 data-nosnippet>285</a> sql0,
<a href=#286 id=286 data-nosnippet>286</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#287 id=287 data-nosnippet>287</a> ParseOptions::default(),
<a href=#288 id=288 data-nosnippet>288</a> )
<a href=#289 id=289 data-nosnippet>289</a> .unwrap();
<a href=#290 id=290 data-nosnippet>290</a> <span class="kw">let </span>result1 = ParserContext::create_with_dialect(
<a href=#291 id=291 data-nosnippet>291</a> sql1,
<a href=#292 id=292 data-nosnippet>292</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#293 id=293 data-nosnippet>293</a> ParseOptions::default(),
<a href=#294 id=294 data-nosnippet>294</a> )
<a href=#295 id=295 data-nosnippet>295</a> .unwrap();
<a href=#296 id=296 data-nosnippet>296</a>
<a href=#297 id=297 data-nosnippet>297</a> <span class="kw">for </span><span class="kw-2">mut </span>result <span class="kw">in </span>[result0, result1] {
<a href=#298 id=298 data-nosnippet>298</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#299 id=299 data-nosnippet>299</a>
<a href=#300 id=300 data-nosnippet>300</a> <span class="kw">let </span>statement = result.remove(<span class="number">0</span>);
<a href=#301 id=301 data-nosnippet>301</a> <span class="macro">assert_matches!</span>(statement, Statement::Copy { .. });
<a href=#302 id=302 data-nosnippet>302</a> <span class="kw">match </span>statement {
<a href=#303 id=303 data-nosnippet>303</a> Copy(copy) =&gt; {
<a href=#304 id=304 data-nosnippet>304</a> <span class="kw">let </span><span class="kw">crate</span>::statements::copy::Copy::CopyTable(CopyTable::To(copy_table)) = copy
<a href=#305 id=305 data-nosnippet>305</a> <span class="kw">else </span>{
<a href=#306 id=306 data-nosnippet>306</a> <span class="macro">unreachable!</span>()
<a href=#307 id=307 data-nosnippet>307</a> };
<a href=#308 id=308 data-nosnippet>308</a> <span class="kw">let </span>table = copy_table.table_name.to_string();
<a href=#309 id=309 data-nosnippet>309</a> <span class="macro">assert_eq!</span>(<span class="string">"catalog0.schema0.tbl"</span>, table);
<a href=#310 id=310 data-nosnippet>310</a>
<a href=#311 id=311 data-nosnippet>311</a> <span class="kw">let </span>file_name = <span class="kw-2">&amp;</span>copy_table.location;
<a href=#312 id=312 data-nosnippet>312</a> <span class="macro">assert_eq!</span>(<span class="string">"tbl_file.parquet"</span>, file_name);
<a href=#313 id=313 data-nosnippet>313</a>
<a href=#314 id=314 data-nosnippet>314</a> <span class="kw">let </span>format = copy_table.format().unwrap();
<a href=#315 id=315 data-nosnippet>315</a> <span class="macro">assert_eq!</span>(<span class="string">"parquet"</span>, format.to_lowercase());
<a href=#316 id=316 data-nosnippet>316</a> }
<a href=#317 id=317 data-nosnippet>317</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#318 id=318 data-nosnippet>318</a> }
<a href=#319 id=319 data-nosnippet>319</a> }
<a href=#320 id=320 data-nosnippet>320</a> }
<a href=#321 id=321 data-nosnippet>321</a>
<a href=#322 id=322 data-nosnippet>322</a> <span class="attr">#[test]
<a href=#323 id=323 data-nosnippet>323</a> </span><span class="kw">fn </span>test_parse_copy_table_from_basic() {
<a href=#324 id=324 data-nosnippet>324</a> <span class="kw">let </span>results = [
<a href=#325 id=325 data-nosnippet>325</a> <span class="string">"COPY catalog0.schema0.tbl FROM 'tbl_file.parquet'"</span>,
<a href=#326 id=326 data-nosnippet>326</a> <span class="string">"COPY catalog0.schema0.tbl FROM 'tbl_file.parquet' WITH (FORMAT = 'parquet')"</span>,
<a href=#327 id=327 data-nosnippet>327</a> ]
<a href=#328 id=328 data-nosnippet>328</a> .iter()
<a href=#329 id=329 data-nosnippet>329</a> .map(|sql| {
<a href=#330 id=330 data-nosnippet>330</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#331 id=331 data-nosnippet>331</a> .unwrap()
<a href=#332 id=332 data-nosnippet>332</a> })
<a href=#333 id=333 data-nosnippet>333</a> .collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;();
<a href=#334 id=334 data-nosnippet>334</a>
<a href=#335 id=335 data-nosnippet>335</a> <span class="kw">for </span><span class="kw-2">mut </span>result <span class="kw">in </span>results {
<a href=#336 id=336 data-nosnippet>336</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#337 id=337 data-nosnippet>337</a>
<a href=#338 id=338 data-nosnippet>338</a> <span class="kw">let </span>statement = result.remove(<span class="number">0</span>);
<a href=#339 id=339 data-nosnippet>339</a> <span class="macro">assert_matches!</span>(statement, Statement::Copy { .. });
<a href=#340 id=340 data-nosnippet>340</a> <span class="kw">match </span>statement {
<a href=#341 id=341 data-nosnippet>341</a> Statement::Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyTable(CopyTable::From(
<a href=#342 id=342 data-nosnippet>342</a> copy_table,
<a href=#343 id=343 data-nosnippet>343</a> ))) =&gt; {
<a href=#344 id=344 data-nosnippet>344</a> <span class="kw">let </span>table = copy_table.table_name.to_string();
<a href=#345 id=345 data-nosnippet>345</a> <span class="macro">assert_eq!</span>(<span class="string">"catalog0.schema0.tbl"</span>, table);
<a href=#346 id=346 data-nosnippet>346</a>
<a href=#347 id=347 data-nosnippet>347</a> <span class="kw">let </span>file_name = <span class="kw-2">&amp;</span>copy_table.location;
<a href=#348 id=348 data-nosnippet>348</a> <span class="macro">assert_eq!</span>(<span class="string">"tbl_file.parquet"</span>, file_name);
<a href=#349 id=349 data-nosnippet>349</a>
<a href=#350 id=350 data-nosnippet>350</a> <span class="kw">let </span>format = copy_table.format().unwrap();
<a href=#351 id=351 data-nosnippet>351</a> <span class="macro">assert_eq!</span>(<span class="string">"parquet"</span>, format.to_lowercase());
<a href=#352 id=352 data-nosnippet>352</a> }
<a href=#353 id=353 data-nosnippet>353</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#354 id=354 data-nosnippet>354</a> }
<a href=#355 id=355 data-nosnippet>355</a> }
<a href=#356 id=356 data-nosnippet>356</a> }
<a href=#357 id=357 data-nosnippet>357</a>
<a href=#358 id=358 data-nosnippet>358</a> <span class="attr">#[test]
<a href=#359 id=359 data-nosnippet>359</a> </span><span class="kw">fn </span>test_parse_copy_table_from() {
<a href=#360 id=360 data-nosnippet>360</a> <span class="kw">struct </span>Test&lt;<span class="lifetime">'a</span>&gt; {
<a href=#361 id=361 data-nosnippet>361</a> sql: <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str,
<a href=#362 id=362 data-nosnippet>362</a> expected_pattern: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#363 id=363 data-nosnippet>363</a> expected_connection: HashMap&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>str, <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt;,
<a href=#364 id=364 data-nosnippet>364</a> }
<a href=#365 id=365 data-nosnippet>365</a>
<a href=#366 id=366 data-nosnippet>366</a> <span class="kw">let </span>tests = [
<a href=#367 id=367 data-nosnippet>367</a> Test {
<a href=#368 id=368 data-nosnippet>368</a> sql: <span class="string">"COPY catalog0.schema0.tbl FROM 'tbl_file.parquet' WITH (PATTERN = 'demo.*')"</span>,
<a href=#369 id=369 data-nosnippet>369</a> expected_pattern: <span class="prelude-val">Some</span>(<span class="string">"demo.*"</span>.into()),
<a href=#370 id=370 data-nosnippet>370</a> expected_connection: HashMap::new(),
<a href=#371 id=371 data-nosnippet>371</a> },
<a href=#372 id=372 data-nosnippet>372</a> Test {
<a href=#373 id=373 data-nosnippet>373</a> sql: <span class="string">"COPY catalog0.schema0.tbl FROM 'tbl_file.parquet' WITH (PATTERN = 'demo.*') CONNECTION (FOO='Bar', ONE='two')"</span>,
<a href=#374 id=374 data-nosnippet>374</a> expected_pattern: <span class="prelude-val">Some</span>(<span class="string">"demo.*"</span>.into()),
<a href=#375 id=375 data-nosnippet>375</a> expected_connection: HashMap::from([(<span class="string">"foo"</span>, <span class="string">"Bar"</span>), (<span class="string">"one"</span>, <span class="string">"two"</span>)]),
<a href=#376 id=376 data-nosnippet>376</a> },
<a href=#377 id=377 data-nosnippet>377</a> ];
<a href=#378 id=378 data-nosnippet>378</a>
<a href=#379 id=379 data-nosnippet>379</a> <span class="kw">for </span>test <span class="kw">in </span>tests {
<a href=#380 id=380 data-nosnippet>380</a> <span class="kw">let </span><span class="kw-2">mut </span>result = ParserContext::create_with_dialect(
<a href=#381 id=381 data-nosnippet>381</a> test.sql,
<a href=#382 id=382 data-nosnippet>382</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#383 id=383 data-nosnippet>383</a> ParseOptions::default(),
<a href=#384 id=384 data-nosnippet>384</a> )
<a href=#385 id=385 data-nosnippet>385</a> .unwrap();
<a href=#386 id=386 data-nosnippet>386</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#387 id=387 data-nosnippet>387</a>
<a href=#388 id=388 data-nosnippet>388</a> <span class="kw">let </span>statement = result.remove(<span class="number">0</span>);
<a href=#389 id=389 data-nosnippet>389</a> <span class="macro">assert_matches!</span>(statement, Statement::Copy { .. });
<a href=#390 id=390 data-nosnippet>390</a> <span class="kw">match </span>statement {
<a href=#391 id=391 data-nosnippet>391</a> Statement::Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyTable(CopyTable::From(
<a href=#392 id=392 data-nosnippet>392</a> copy_table,
<a href=#393 id=393 data-nosnippet>393</a> ))) =&gt; {
<a href=#394 id=394 data-nosnippet>394</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(expected_pattern) = test.expected_pattern {
<a href=#395 id=395 data-nosnippet>395</a> <span class="macro">assert_eq!</span>(copy_table.pattern().unwrap(), expected_pattern);
<a href=#396 id=396 data-nosnippet>396</a> }
<a href=#397 id=397 data-nosnippet>397</a> <span class="macro">assert_eq!</span>(copy_table.connection.to_str_map(), test.expected_connection);
<a href=#398 id=398 data-nosnippet>398</a> }
<a href=#399 id=399 data-nosnippet>399</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#400 id=400 data-nosnippet>400</a> }
<a href=#401 id=401 data-nosnippet>401</a> }
<a href=#402 id=402 data-nosnippet>402</a> }
<a href=#403 id=403 data-nosnippet>403</a>
<a href=#404 id=404 data-nosnippet>404</a> <span class="attr">#[test]
<a href=#405 id=405 data-nosnippet>405</a> </span><span class="kw">fn </span>test_parse_copy_table_from_csv_options() {
<a href=#406 id=406 data-nosnippet>406</a> <span class="kw">let </span>sql = <span class="string">"COPY my_table FROM '/tmp/test.csv' WITH (FORMAT = 'CSV', SKIP_BAD_RECORDS = 'false', HEADERS = 'false')"</span>;
<a href=#407 id=407 data-nosnippet>407</a> <span class="kw">let </span><span class="kw-2">mut </span>result =
<a href=#408 id=408 data-nosnippet>408</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#409 id=409 data-nosnippet>409</a> .unwrap();
<a href=#410 id=410 data-nosnippet>410</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#411 id=411 data-nosnippet>411</a>
<a href=#412 id=412 data-nosnippet>412</a> <span class="kw">let </span>statement = result.remove(<span class="number">0</span>);
<a href=#413 id=413 data-nosnippet>413</a> <span class="macro">assert_matches!</span>(statement, Statement::Copy { .. });
<a href=#414 id=414 data-nosnippet>414</a> <span class="kw">match </span>statement {
<a href=#415 id=415 data-nosnippet>415</a> Statement::Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyTable(CopyTable::From(
<a href=#416 id=416 data-nosnippet>416</a> copy_table,
<a href=#417 id=417 data-nosnippet>417</a> ))) =&gt; {
<a href=#418 id=418 data-nosnippet>418</a> <span class="macro">assert_eq!</span>(copy_table.with.get(<span class="string">"format"</span>), <span class="prelude-val">Some</span>(<span class="string">"CSV"</span>));
<a href=#419 id=419 data-nosnippet>419</a> <span class="macro">assert_eq!</span>(copy_table.with.get(<span class="string">"skip_bad_records"</span>), <span class="prelude-val">Some</span>(<span class="string">"false"</span>));
<a href=#420 id=420 data-nosnippet>420</a> <span class="macro">assert_eq!</span>(copy_table.with.get(<span class="string">"headers"</span>), <span class="prelude-val">Some</span>(<span class="string">"false"</span>));
<a href=#421 id=421 data-nosnippet>421</a> }
<a href=#422 id=422 data-nosnippet>422</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#423 id=423 data-nosnippet>423</a> }
<a href=#424 id=424 data-nosnippet>424</a> }
<a href=#425 id=425 data-nosnippet>425</a>
<a href=#426 id=426 data-nosnippet>426</a> <span class="attr">#[test]
<a href=#427 id=427 data-nosnippet>427</a> </span><span class="kw">fn </span>test_parse_copy_table_to() {
<a href=#428 id=428 data-nosnippet>428</a> <span class="kw">struct </span>Test&lt;<span class="lifetime">'a</span>&gt; {
<a href=#429 id=429 data-nosnippet>429</a> sql: <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str,
<a href=#430 id=430 data-nosnippet>430</a> expected_connection: HashMap&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>str, <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt;,
<a href=#431 id=431 data-nosnippet>431</a> }
<a href=#432 id=432 data-nosnippet>432</a>
<a href=#433 id=433 data-nosnippet>433</a> <span class="kw">let </span>tests = [
<a href=#434 id=434 data-nosnippet>434</a> Test {
<a href=#435 id=435 data-nosnippet>435</a> sql: <span class="string">"COPY catalog0.schema0.tbl TO 'tbl_file.parquet' "</span>,
<a href=#436 id=436 data-nosnippet>436</a> expected_connection: HashMap::new(),
<a href=#437 id=437 data-nosnippet>437</a> },
<a href=#438 id=438 data-nosnippet>438</a> Test {
<a href=#439 id=439 data-nosnippet>439</a> sql: <span class="string">"COPY catalog0.schema0.tbl TO 'tbl_file.parquet' CONNECTION (FOO='Bar', ONE='two')"</span>,
<a href=#440 id=440 data-nosnippet>440</a> expected_connection: HashMap::from([(<span class="string">"foo"</span>, <span class="string">"Bar"</span>), (<span class="string">"one"</span>, <span class="string">"two"</span>)]),
<a href=#441 id=441 data-nosnippet>441</a> },
<a href=#442 id=442 data-nosnippet>442</a> Test {
<a href=#443 id=443 data-nosnippet>443</a> sql: <span class="string">"COPY catalog0.schema0.tbl TO 'tbl_file.parquet' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>,
<a href=#444 id=444 data-nosnippet>444</a> expected_connection: HashMap::from([(<span class="string">"foo"</span>, <span class="string">"Bar"</span>), (<span class="string">"one"</span>, <span class="string">"two"</span>)]),
<a href=#445 id=445 data-nosnippet>445</a> },
<a href=#446 id=446 data-nosnippet>446</a> ];
<a href=#447 id=447 data-nosnippet>447</a>
<a href=#448 id=448 data-nosnippet>448</a> <span class="kw">for </span>test <span class="kw">in </span>tests {
<a href=#449 id=449 data-nosnippet>449</a> <span class="kw">let </span><span class="kw-2">mut </span>result = ParserContext::create_with_dialect(
<a href=#450 id=450 data-nosnippet>450</a> test.sql,
<a href=#451 id=451 data-nosnippet>451</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#452 id=452 data-nosnippet>452</a> ParseOptions::default(),
<a href=#453 id=453 data-nosnippet>453</a> )
<a href=#454 id=454 data-nosnippet>454</a> .unwrap();
<a href=#455 id=455 data-nosnippet>455</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#456 id=456 data-nosnippet>456</a>
<a href=#457 id=457 data-nosnippet>457</a> <span class="kw">let </span>statement = result.remove(<span class="number">0</span>);
<a href=#458 id=458 data-nosnippet>458</a> <span class="macro">assert_matches!</span>(statement, Statement::Copy { .. });
<a href=#459 id=459 data-nosnippet>459</a> <span class="kw">match </span>statement {
<a href=#460 id=460 data-nosnippet>460</a> Statement::Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyTable(CopyTable::To(
<a href=#461 id=461 data-nosnippet>461</a> copy_table,
<a href=#462 id=462 data-nosnippet>462</a> ))) =&gt; {
<a href=#463 id=463 data-nosnippet>463</a> <span class="macro">assert_eq!</span>(copy_table.connection.to_str_map(), test.expected_connection);
<a href=#464 id=464 data-nosnippet>464</a> }
<a href=#465 id=465 data-nosnippet>465</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#466 id=466 data-nosnippet>466</a> }
<a href=#467 id=467 data-nosnippet>467</a> }
<a href=#468 id=468 data-nosnippet>468</a> }
<a href=#469 id=469 data-nosnippet>469</a>
<a href=#470 id=470 data-nosnippet>470</a> <span class="attr">#[test]
<a href=#471 id=471 data-nosnippet>471</a> </span><span class="kw">fn </span>test_copy_database_to() {
<a href=#472 id=472 data-nosnippet>472</a> <span class="kw">let </span>sql = <span class="string">"COPY DATABASE catalog0.schema0 TO 'tbl_file.parquet' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>;
<a href=#473 id=473 data-nosnippet>473</a> <span class="kw">let </span>stmt =
<a href=#474 id=474 data-nosnippet>474</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#475 id=475 data-nosnippet>475</a> .unwrap()
<a href=#476 id=476 data-nosnippet>476</a> .pop()
<a href=#477 id=477 data-nosnippet>477</a> .unwrap();
<a href=#478 id=478 data-nosnippet>478</a>
<a href=#479 id=479 data-nosnippet>479</a> <span class="kw">let </span>Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyDatabase(stmt)) = stmt <span class="kw">else </span>{
<a href=#480 id=480 data-nosnippet>480</a> <span class="macro">unreachable!</span>()
<a href=#481 id=481 data-nosnippet>481</a> };
<a href=#482 id=482 data-nosnippet>482</a>
<a href=#483 id=483 data-nosnippet>483</a> <span class="kw">let </span>CopyDatabase::To(stmt) = stmt <span class="kw">else </span>{
<a href=#484 id=484 data-nosnippet>484</a> <span class="macro">unreachable!</span>()
<a href=#485 id=485 data-nosnippet>485</a> };
<a href=#486 id=486 data-nosnippet>486</a>
<a href=#487 id=487 data-nosnippet>487</a> <span class="macro">assert_eq!</span>(
<a href=#488 id=488 data-nosnippet>488</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"catalog0"</span>), Ident::new(<span class="string">"schema0"</span>)]),
<a href=#489 id=489 data-nosnippet>489</a> stmt.database_name
<a href=#490 id=490 data-nosnippet>490</a> );
<a href=#491 id=491 data-nosnippet>491</a> <span class="macro">assert_eq!</span>(
<a href=#492 id=492 data-nosnippet>492</a> [(<span class="string">"format"</span>, <span class="string">"parquet"</span>)]
<a href=#493 id=493 data-nosnippet>493</a> .into_iter()
<a href=#494 id=494 data-nosnippet>494</a> .collect::&lt;HashMap&lt;<span class="kw">_</span>, <span class="kw">_</span>&gt;&gt;(),
<a href=#495 id=495 data-nosnippet>495</a> stmt.with.to_str_map()
<a href=#496 id=496 data-nosnippet>496</a> );
<a href=#497 id=497 data-nosnippet>497</a>
<a href=#498 id=498 data-nosnippet>498</a> <span class="macro">assert_eq!</span>(
<a href=#499 id=499 data-nosnippet>499</a> [(<span class="string">"foo"</span>, <span class="string">"Bar"</span>), (<span class="string">"one"</span>, <span class="string">"two"</span>)]
<a href=#500 id=500 data-nosnippet>500</a> .into_iter()
<a href=#501 id=501 data-nosnippet>501</a> .collect::&lt;HashMap&lt;<span class="kw">_</span>, <span class="kw">_</span>&gt;&gt;(),
<a href=#502 id=502 data-nosnippet>502</a> stmt.connection.to_str_map()
<a href=#503 id=503 data-nosnippet>503</a> );
<a href=#504 id=504 data-nosnippet>504</a> }
<a href=#505 id=505 data-nosnippet>505</a>
<a href=#506 id=506 data-nosnippet>506</a> <span class="attr">#[test]
<a href=#507 id=507 data-nosnippet>507</a> </span><span class="kw">fn </span>test_copy_database_from() {
<a href=#508 id=508 data-nosnippet>508</a> <span class="kw">let </span>sql = <span class="string">"COPY DATABASE catalog0.schema0 FROM '/a/b/c/' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>;
<a href=#509 id=509 data-nosnippet>509</a> <span class="kw">let </span>stmt =
<a href=#510 id=510 data-nosnippet>510</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#511 id=511 data-nosnippet>511</a> .unwrap()
<a href=#512 id=512 data-nosnippet>512</a> .pop()
<a href=#513 id=513 data-nosnippet>513</a> .unwrap();
<a href=#514 id=514 data-nosnippet>514</a>
<a href=#515 id=515 data-nosnippet>515</a> <span class="kw">let </span>Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyDatabase(stmt)) = stmt <span class="kw">else </span>{
<a href=#516 id=516 data-nosnippet>516</a> <span class="macro">unreachable!</span>()
<a href=#517 id=517 data-nosnippet>517</a> };
<a href=#518 id=518 data-nosnippet>518</a>
<a href=#519 id=519 data-nosnippet>519</a> <span class="kw">let </span>CopyDatabase::From(stmt) = stmt <span class="kw">else </span>{
<a href=#520 id=520 data-nosnippet>520</a> <span class="macro">unreachable!</span>()
<a href=#521 id=521 data-nosnippet>521</a> };
<a href=#522 id=522 data-nosnippet>522</a>
<a href=#523 id=523 data-nosnippet>523</a> <span class="macro">assert_eq!</span>(
<a href=#524 id=524 data-nosnippet>524</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"catalog0"</span>), Ident::new(<span class="string">"schema0"</span>)]),
<a href=#525 id=525 data-nosnippet>525</a> stmt.database_name
<a href=#526 id=526 data-nosnippet>526</a> );
<a href=#527 id=527 data-nosnippet>527</a> <span class="macro">assert_eq!</span>(
<a href=#528 id=528 data-nosnippet>528</a> [(<span class="string">"format"</span>, <span class="string">"parquet"</span>)]
<a href=#529 id=529 data-nosnippet>529</a> .into_iter()
<a href=#530 id=530 data-nosnippet>530</a> .collect::&lt;HashMap&lt;<span class="kw">_</span>, <span class="kw">_</span>&gt;&gt;(),
<a href=#531 id=531 data-nosnippet>531</a> stmt.with.to_str_map()
<a href=#532 id=532 data-nosnippet>532</a> );
<a href=#533 id=533 data-nosnippet>533</a>
<a href=#534 id=534 data-nosnippet>534</a> <span class="macro">assert_eq!</span>(
<a href=#535 id=535 data-nosnippet>535</a> [(<span class="string">"foo"</span>, <span class="string">"Bar"</span>), (<span class="string">"one"</span>, <span class="string">"two"</span>)]
<a href=#536 id=536 data-nosnippet>536</a> .into_iter()
<a href=#537 id=537 data-nosnippet>537</a> .collect::&lt;HashMap&lt;<span class="kw">_</span>, <span class="kw">_</span>&gt;&gt;(),
<a href=#538 id=538 data-nosnippet>538</a> stmt.connection.to_str_map()
<a href=#539 id=539 data-nosnippet>539</a> );
<a href=#540 id=540 data-nosnippet>540</a> }
<a href=#541 id=541 data-nosnippet>541</a>
<a href=#542 id=542 data-nosnippet>542</a> <span class="attr">#[test]
<a href=#543 id=543 data-nosnippet>543</a> </span><span class="kw">fn </span>test_copy_query_to() {
<a href=#544 id=544 data-nosnippet>544</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM tbl WHERE ts &gt; 10) TO 'tbl_file.parquet' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>;
<a href=#545 id=545 data-nosnippet>545</a> <span class="kw">let </span>stmt =
<a href=#546 id=546 data-nosnippet>546</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#547 id=547 data-nosnippet>547</a> .unwrap()
<a href=#548 id=548 data-nosnippet>548</a> .pop()
<a href=#549 id=549 data-nosnippet>549</a> .unwrap();
<a href=#550 id=550 data-nosnippet>550</a>
<a href=#551 id=551 data-nosnippet>551</a> <span class="kw">let </span>Copy(<span class="kw">crate</span>::statements::copy::Copy::CopyQueryTo(stmt)) = stmt <span class="kw">else </span>{
<a href=#552 id=552 data-nosnippet>552</a> <span class="macro">unreachable!</span>()
<a href=#553 id=553 data-nosnippet>553</a> };
<a href=#554 id=554 data-nosnippet>554</a>
<a href=#555 id=555 data-nosnippet>555</a> <span class="kw">let </span>query = ParserContext::create_with_dialect(
<a href=#556 id=556 data-nosnippet>556</a> <span class="string">"SELECT * FROM tbl WHERE ts &gt; 10"</span>,
<a href=#557 id=557 data-nosnippet>557</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#558 id=558 data-nosnippet>558</a> ParseOptions::default(),
<a href=#559 id=559 data-nosnippet>559</a> )
<a href=#560 id=560 data-nosnippet>560</a> .unwrap()
<a href=#561 id=561 data-nosnippet>561</a> .remove(<span class="number">0</span>);
<a href=#562 id=562 data-nosnippet>562</a>
<a href=#563 id=563 data-nosnippet>563</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>query, stmt.query.as_ref());
<a href=#564 id=564 data-nosnippet>564</a> <span class="macro">assert_eq!</span>(
<a href=#565 id=565 data-nosnippet>565</a> [(<span class="string">"format"</span>, <span class="string">"parquet"</span>)]
<a href=#566 id=566 data-nosnippet>566</a> .into_iter()
<a href=#567 id=567 data-nosnippet>567</a> .collect::&lt;HashMap&lt;<span class="kw">_</span>, <span class="kw">_</span>&gt;&gt;(),
<a href=#568 id=568 data-nosnippet>568</a> stmt.arg.with.to_str_map()
<a href=#569 id=569 data-nosnippet>569</a> );
<a href=#570 id=570 data-nosnippet>570</a>
<a href=#571 id=571 data-nosnippet>571</a> <span class="macro">assert_eq!</span>(
<a href=#572 id=572 data-nosnippet>572</a> [(<span class="string">"foo"</span>, <span class="string">"Bar"</span>), (<span class="string">"one"</span>, <span class="string">"two"</span>)]
<a href=#573 id=573 data-nosnippet>573</a> .into_iter()
<a href=#574 id=574 data-nosnippet>574</a> .collect::&lt;HashMap&lt;<span class="kw">_</span>, <span class="kw">_</span>&gt;&gt;(),
<a href=#575 id=575 data-nosnippet>575</a> stmt.arg.connection.to_str_map()
<a href=#576 id=576 data-nosnippet>576</a> );
<a href=#577 id=577 data-nosnippet>577</a> }
<a href=#578 id=578 data-nosnippet>578</a>
<a href=#579 id=579 data-nosnippet>579</a> <span class="attr">#[test]
<a href=#580 id=580 data-nosnippet>580</a> </span><span class="kw">fn </span>test_invalid_copy_query_to() {
<a href=#581 id=581 data-nosnippet>581</a> {
<a href=#582 id=582 data-nosnippet>582</a> <span class="kw">let </span>sql = <span class="string">"COPY SELECT * FROM tbl WHERE ts &gt; 10 TO 'tbl_file.parquet' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>;
<a href=#583 id=583 data-nosnippet>583</a>
<a href=#584 id=584 data-nosnippet>584</a> <span class="macro">assert!</span>(
<a href=#585 id=585 data-nosnippet>585</a> ParserContext::create_with_dialect(
<a href=#586 id=586 data-nosnippet>586</a> sql,
<a href=#587 id=587 data-nosnippet>587</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#588 id=588 data-nosnippet>588</a> ParseOptions::default()
<a href=#589 id=589 data-nosnippet>589</a> )
<a href=#590 id=590 data-nosnippet>590</a> .is_err()
<a href=#591 id=591 data-nosnippet>591</a> )
<a href=#592 id=592 data-nosnippet>592</a> }
<a href=#593 id=593 data-nosnippet>593</a> {
<a href=#594 id=594 data-nosnippet>594</a> <span class="kw">let </span>sql = <span class="string">"COPY SELECT * FROM tbl WHERE ts &gt; 10) TO 'tbl_file.parquet' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>;
<a href=#595 id=595 data-nosnippet>595</a>
<a href=#596 id=596 data-nosnippet>596</a> <span class="macro">assert!</span>(
<a href=#597 id=597 data-nosnippet>597</a> ParserContext::create_with_dialect(
<a href=#598 id=598 data-nosnippet>598</a> sql,
<a href=#599 id=599 data-nosnippet>599</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#600 id=600 data-nosnippet>600</a> ParseOptions::default()
<a href=#601 id=601 data-nosnippet>601</a> )
<a href=#602 id=602 data-nosnippet>602</a> .is_err()
<a href=#603 id=603 data-nosnippet>603</a> )
<a href=#604 id=604 data-nosnippet>604</a> }
<a href=#605 id=605 data-nosnippet>605</a> {
<a href=#606 id=606 data-nosnippet>606</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM tbl WHERE ts &gt; 10 TO 'tbl_file.parquet' WITH (FORMAT = 'parquet') CONNECTION (FOO='Bar', ONE='two')"</span>;
<a href=#607 id=607 data-nosnippet>607</a>
<a href=#608 id=608 data-nosnippet>608</a> <span class="macro">assert!</span>(
<a href=#609 id=609 data-nosnippet>609</a> ParserContext::create_with_dialect(
<a href=#610 id=610 data-nosnippet>610</a> sql,
<a href=#611 id=611 data-nosnippet>611</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#612 id=612 data-nosnippet>612</a> ParseOptions::default()
<a href=#613 id=613 data-nosnippet>613</a> )
<a href=#614 id=614 data-nosnippet>614</a> .is_err()
<a href=#615 id=615 data-nosnippet>615</a> )
<a href=#616 id=616 data-nosnippet>616</a> }
<a href=#617 id=617 data-nosnippet>617</a> }
<a href=#618 id=618 data-nosnippet>618</a>
<a href=#619 id=619 data-nosnippet>619</a> <span class="attr">#[test]
<a href=#620 id=620 data-nosnippet>620</a> </span><span class="kw">fn </span>test_copy_query_to_stdout() {
<a href=#621 id=621 data-nosnippet>621</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM tbl WHERE ts &gt; 10) TO STDOUT WITH (FORMAT = 'csv')"</span>;
<a href=#622 id=622 data-nosnippet>622</a> <span class="kw">let </span>stmt =
<a href=#623 id=623 data-nosnippet>623</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#624 id=624 data-nosnippet>624</a> .unwrap()
<a href=#625 id=625 data-nosnippet>625</a> .pop()
<a href=#626 id=626 data-nosnippet>626</a> .unwrap();
<a href=#627 id=627 data-nosnippet>627</a>
<a href=#628 id=628 data-nosnippet>628</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#629 id=629 data-nosnippet>629</a> <span class="string">"SELECT * FROM tbl WHERE ts &gt; 10"</span>,
<a href=#630 id=630 data-nosnippet>630</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#631 id=631 data-nosnippet>631</a> ParseOptions::default(),
<a href=#632 id=632 data-nosnippet>632</a> )
<a href=#633 id=633 data-nosnippet>633</a> .unwrap()
<a href=#634 id=634 data-nosnippet>634</a> .remove(<span class="number">0</span>);
<a href=#635 id=635 data-nosnippet>635</a>
<a href=#636 id=636 data-nosnippet>636</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#637 id=637 data-nosnippet>637</a> }
<a href=#638 id=638 data-nosnippet>638</a>
<a href=#639 id=639 data-nosnippet>639</a> <span class="attr">#[test]
<a href=#640 id=640 data-nosnippet>640</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_without_format() {
<a href=#641 id=641 data-nosnippet>641</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT generate_series(1, 2), generate_series(2, 3)) TO STDOUT"</span>;
<a href=#642 id=642 data-nosnippet>642</a> <span class="kw">let </span>stmt =
<a href=#643 id=643 data-nosnippet>643</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#644 id=644 data-nosnippet>644</a> .unwrap()
<a href=#645 id=645 data-nosnippet>645</a> .pop()
<a href=#646 id=646 data-nosnippet>646</a> .unwrap();
<a href=#647 id=647 data-nosnippet>647</a>
<a href=#648 id=648 data-nosnippet>648</a> <span class="kw">let </span>query_str = <span class="string">"SELECT generate_series(1, 2), generate_series(2, 3)"</span>;
<a href=#649 id=649 data-nosnippet>649</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#650 id=650 data-nosnippet>650</a> query_str,
<a href=#651 id=651 data-nosnippet>651</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#652 id=652 data-nosnippet>652</a> ParseOptions::default(),
<a href=#653 id=653 data-nosnippet>653</a> )
<a href=#654 id=654 data-nosnippet>654</a> .unwrap()
<a href=#655 id=655 data-nosnippet>655</a> .remove(<span class="number">0</span>);
<a href=#656 id=656 data-nosnippet>656</a>
<a href=#657 id=657 data-nosnippet>657</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#658 id=658 data-nosnippet>658</a> }
<a href=#659 id=659 data-nosnippet>659</a>
<a href=#660 id=660 data-nosnippet>660</a> <span class="attr">#[test]
<a href=#661 id=661 data-nosnippet>661</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_with_binary_format() {
<a href=#662 id=662 data-nosnippet>662</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT WITH (FORMAT binary)"</span>;
<a href=#663 id=663 data-nosnippet>663</a> <span class="kw">let </span>result =
<a href=#664 id=664 data-nosnippet>664</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#665 id=665 data-nosnippet>665</a>
<a href=#666 id=666 data-nosnippet>666</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#667 id=667 data-nosnippet>667</a> <span class="macro">panic!</span>(
<a href=#668 id=668 data-nosnippet>668</a> <span class="string">"COPY TO STDOUT WITH (FORMAT binary) should parse without error, got: {:?}"</span>,
<a href=#669 id=669 data-nosnippet>669</a> e
<a href=#670 id=670 data-nosnippet>670</a> );
<a href=#671 id=671 data-nosnippet>671</a> }
<a href=#672 id=672 data-nosnippet>672</a>
<a href=#673 id=673 data-nosnippet>673</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#674 id=674 data-nosnippet>674</a>
<a href=#675 id=675 data-nosnippet>675</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#676 id=676 data-nosnippet>676</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#677 id=677 data-nosnippet>677</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#678 id=678 data-nosnippet>678</a> ParseOptions::default(),
<a href=#679 id=679 data-nosnippet>679</a> )
<a href=#680 id=680 data-nosnippet>680</a> .unwrap()
<a href=#681 id=681 data-nosnippet>681</a> .remove(<span class="number">0</span>);
<a href=#682 id=682 data-nosnippet>682</a>
<a href=#683 id=683 data-nosnippet>683</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#684 id=684 data-nosnippet>684</a> }
<a href=#685 id=685 data-nosnippet>685</a>
<a href=#686 id=686 data-nosnippet>686</a> <span class="attr">#[test]
<a href=#687 id=687 data-nosnippet>687</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_with_csv_format() {
<a href=#688 id=688 data-nosnippet>688</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT WITH (FORMAT csv)"</span>;
<a href=#689 id=689 data-nosnippet>689</a> <span class="kw">let </span>result =
<a href=#690 id=690 data-nosnippet>690</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#691 id=691 data-nosnippet>691</a>
<a href=#692 id=692 data-nosnippet>692</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#693 id=693 data-nosnippet>693</a> <span class="macro">panic!</span>(
<a href=#694 id=694 data-nosnippet>694</a> <span class="string">"COPY TO STDOUT WITH (FORMAT csv) should parse without error, got: {:?}"</span>,
<a href=#695 id=695 data-nosnippet>695</a> e
<a href=#696 id=696 data-nosnippet>696</a> );
<a href=#697 id=697 data-nosnippet>697</a> }
<a href=#698 id=698 data-nosnippet>698</a>
<a href=#699 id=699 data-nosnippet>699</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#700 id=700 data-nosnippet>700</a>
<a href=#701 id=701 data-nosnippet>701</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#702 id=702 data-nosnippet>702</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#703 id=703 data-nosnippet>703</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#704 id=704 data-nosnippet>704</a> ParseOptions::default(),
<a href=#705 id=705 data-nosnippet>705</a> )
<a href=#706 id=706 data-nosnippet>706</a> .unwrap()
<a href=#707 id=707 data-nosnippet>707</a> .remove(<span class="number">0</span>);
<a href=#708 id=708 data-nosnippet>708</a>
<a href=#709 id=709 data-nosnippet>709</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#710 id=710 data-nosnippet>710</a> }
<a href=#711 id=711 data-nosnippet>711</a>
<a href=#712 id=712 data-nosnippet>712</a> <span class="attr">#[test]
<a href=#713 id=713 data-nosnippet>713</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_with_equals_format() {
<a href=#714 id=714 data-nosnippet>714</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT WITH (FORMAT = 'binary')"</span>;
<a href=#715 id=715 data-nosnippet>715</a> <span class="kw">let </span>result =
<a href=#716 id=716 data-nosnippet>716</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#717 id=717 data-nosnippet>717</a>
<a href=#718 id=718 data-nosnippet>718</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#719 id=719 data-nosnippet>719</a> <span class="macro">panic!</span>(
<a href=#720 id=720 data-nosnippet>720</a> <span class="string">"COPY TO STDOUT WITH (FORMAT = 'binary') should parse without error, got: {:?}"</span>,
<a href=#721 id=721 data-nosnippet>721</a> e
<a href=#722 id=722 data-nosnippet>722</a> );
<a href=#723 id=723 data-nosnippet>723</a> }
<a href=#724 id=724 data-nosnippet>724</a>
<a href=#725 id=725 data-nosnippet>725</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#726 id=726 data-nosnippet>726</a>
<a href=#727 id=727 data-nosnippet>727</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#728 id=728 data-nosnippet>728</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#729 id=729 data-nosnippet>729</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#730 id=730 data-nosnippet>730</a> ParseOptions::default(),
<a href=#731 id=731 data-nosnippet>731</a> )
<a href=#732 id=732 data-nosnippet>732</a> .unwrap()
<a href=#733 id=733 data-nosnippet>733</a> .remove(<span class="number">0</span>);
<a href=#734 id=734 data-nosnippet>734</a>
<a href=#735 id=735 data-nosnippet>735</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#736 id=736 data-nosnippet>736</a> }
<a href=#737 id=737 data-nosnippet>737</a>
<a href=#738 id=738 data-nosnippet>738</a> <span class="attr">#[test]
<a href=#739 id=739 data-nosnippet>739</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_with_multiple_options() {
<a href=#740 id=740 data-nosnippet>740</a> <span class="kw">let </span>sql =
<a href=#741 id=741 data-nosnippet>741</a> <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT WITH (FORMAT csv, DELIMITER ',', HEADER)"</span>;
<a href=#742 id=742 data-nosnippet>742</a> <span class="kw">let </span>result =
<a href=#743 id=743 data-nosnippet>743</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#744 id=744 data-nosnippet>744</a>
<a href=#745 id=745 data-nosnippet>745</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#746 id=746 data-nosnippet>746</a> <span class="macro">panic!</span>(
<a href=#747 id=747 data-nosnippet>747</a> <span class="string">"COPY TO STDOUT WITH multiple options should parse without error, got: {:?}"</span>,
<a href=#748 id=748 data-nosnippet>748</a> e
<a href=#749 id=749 data-nosnippet>749</a> );
<a href=#750 id=750 data-nosnippet>750</a> }
<a href=#751 id=751 data-nosnippet>751</a>
<a href=#752 id=752 data-nosnippet>752</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#753 id=753 data-nosnippet>753</a>
<a href=#754 id=754 data-nosnippet>754</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#755 id=755 data-nosnippet>755</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#756 id=756 data-nosnippet>756</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#757 id=757 data-nosnippet>757</a> ParseOptions::default(),
<a href=#758 id=758 data-nosnippet>758</a> )
<a href=#759 id=759 data-nosnippet>759</a> .unwrap()
<a href=#760 id=760 data-nosnippet>760</a> .remove(<span class="number">0</span>);
<a href=#761 id=761 data-nosnippet>761</a>
<a href=#762 id=762 data-nosnippet>762</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#763 id=763 data-nosnippet>763</a> }
<a href=#764 id=764 data-nosnippet>764</a>
<a href=#765 id=765 data-nosnippet>765</a> <span class="attr">#[test]
<a href=#766 id=766 data-nosnippet>766</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_without_with_keyword() {
<a href=#767 id=767 data-nosnippet>767</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT (FORMAT binary)"</span>;
<a href=#768 id=768 data-nosnippet>768</a> <span class="kw">let </span>result =
<a href=#769 id=769 data-nosnippet>769</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#770 id=770 data-nosnippet>770</a>
<a href=#771 id=771 data-nosnippet>771</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#772 id=772 data-nosnippet>772</a> <span class="macro">panic!</span>(
<a href=#773 id=773 data-nosnippet>773</a> <span class="string">"COPY TO STDOUT (FORMAT binary) without WITH keyword should parse without error, got: {:?}"</span>,
<a href=#774 id=774 data-nosnippet>774</a> e
<a href=#775 id=775 data-nosnippet>775</a> );
<a href=#776 id=776 data-nosnippet>776</a> }
<a href=#777 id=777 data-nosnippet>777</a>
<a href=#778 id=778 data-nosnippet>778</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#779 id=779 data-nosnippet>779</a>
<a href=#780 id=780 data-nosnippet>780</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#781 id=781 data-nosnippet>781</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#782 id=782 data-nosnippet>782</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#783 id=783 data-nosnippet>783</a> ParseOptions::default(),
<a href=#784 id=784 data-nosnippet>784</a> )
<a href=#785 id=785 data-nosnippet>785</a> .unwrap()
<a href=#786 id=786 data-nosnippet>786</a> .remove(<span class="number">0</span>);
<a href=#787 id=787 data-nosnippet>787</a>
<a href=#788 id=788 data-nosnippet>788</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#789 id=789 data-nosnippet>789</a> }
<a href=#790 id=790 data-nosnippet>790</a>
<a href=#791 id=791 data-nosnippet>791</a> <span class="attr">#[test]
<a href=#792 id=792 data-nosnippet>792</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_without_with_csv_format() {
<a href=#793 id=793 data-nosnippet>793</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT (FORMAT csv)"</span>;
<a href=#794 id=794 data-nosnippet>794</a> <span class="kw">let </span>result =
<a href=#795 id=795 data-nosnippet>795</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#796 id=796 data-nosnippet>796</a>
<a href=#797 id=797 data-nosnippet>797</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#798 id=798 data-nosnippet>798</a> <span class="macro">panic!</span>(
<a href=#799 id=799 data-nosnippet>799</a> <span class="string">"COPY TO STDOUT (FORMAT csv) without WITH keyword should parse without error, got: {:?}"</span>,
<a href=#800 id=800 data-nosnippet>800</a> e
<a href=#801 id=801 data-nosnippet>801</a> );
<a href=#802 id=802 data-nosnippet>802</a> }
<a href=#803 id=803 data-nosnippet>803</a>
<a href=#804 id=804 data-nosnippet>804</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#805 id=805 data-nosnippet>805</a>
<a href=#806 id=806 data-nosnippet>806</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#807 id=807 data-nosnippet>807</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#808 id=808 data-nosnippet>808</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#809 id=809 data-nosnippet>809</a> ParseOptions::default(),
<a href=#810 id=810 data-nosnippet>810</a> )
<a href=#811 id=811 data-nosnippet>811</a> .unwrap()
<a href=#812 id=812 data-nosnippet>812</a> .remove(<span class="number">0</span>);
<a href=#813 id=813 data-nosnippet>813</a>
<a href=#814 id=814 data-nosnippet>814</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#815 id=815 data-nosnippet>815</a> }
<a href=#816 id=816 data-nosnippet>816</a>
<a href=#817 id=817 data-nosnippet>817</a> <span class="attr">#[test]
<a href=#818 id=818 data-nosnippet>818</a> </span><span class="kw">fn </span>test_copy_query_to_stdout_without_with_multiple_options() {
<a href=#819 id=819 data-nosnippet>819</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT (FORMAT csv, DELIMITER ',', HEADER)"</span>;
<a href=#820 id=820 data-nosnippet>820</a> <span class="kw">let </span>result =
<a href=#821 id=821 data-nosnippet>821</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#822 id=822 data-nosnippet>822</a>
<a href=#823 id=823 data-nosnippet>823</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="kw-2">&amp;</span>result {
<a href=#824 id=824 data-nosnippet>824</a> <span class="macro">panic!</span>(
<a href=#825 id=825 data-nosnippet>825</a> <span class="string">"COPY TO STDOUT (FORMAT csv, ...) without WITH keyword should parse without error, got: {:?}"</span>,
<a href=#826 id=826 data-nosnippet>826</a> e
<a href=#827 id=827 data-nosnippet>827</a> );
<a href=#828 id=828 data-nosnippet>828</a> }
<a href=#829 id=829 data-nosnippet>829</a>
<a href=#830 id=830 data-nosnippet>830</a> <span class="kw">let </span>stmt = result.unwrap().pop().unwrap();
<a href=#831 id=831 data-nosnippet>831</a>
<a href=#832 id=832 data-nosnippet>832</a> <span class="kw">let </span>expected_query = ParserContext::create_with_dialect(
<a href=#833 id=833 data-nosnippet>833</a> <span class="string">"SELECT * FROM test_table"</span>,
<a href=#834 id=834 data-nosnippet>834</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#835 id=835 data-nosnippet>835</a> ParseOptions::default(),
<a href=#836 id=836 data-nosnippet>836</a> )
<a href=#837 id=837 data-nosnippet>837</a> .unwrap()
<a href=#838 id=838 data-nosnippet>838</a> .remove(<span class="number">0</span>);
<a href=#839 id=839 data-nosnippet>839</a>
<a href=#840 id=840 data-nosnippet>840</a> <span class="macro">assert_eq!</span>(<span class="kw-2">&amp;</span>expected_query, <span class="kw-2">&amp;</span>stmt);
<a href=#841 id=841 data-nosnippet>841</a> }
<a href=#842 id=842 data-nosnippet>842</a>
<a href=#843 id=843 data-nosnippet>843</a> <span class="attr">#[test]
<a href=#844 id=844 data-nosnippet>844</a> </span><span class="kw">fn </span>test_invalid_copy_query() {
<a href=#845 id=845 data-nosnippet>845</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT (FORMAT csv"</span>;
<a href=#846 id=846 data-nosnippet>846</a> <span class="kw">let </span>result =
<a href=#847 id=847 data-nosnippet>847</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#848 id=848 data-nosnippet>848</a>
<a href=#849 id=849 data-nosnippet>849</a> <span class="macro">assert!</span>(result.is_err());
<a href=#850 id=850 data-nosnippet>850</a>
<a href=#851 id=851 data-nosnippet>851</a> <span class="kw">let </span>sql = <span class="string">"COPY (SELECT * FROM test_table) TO STDOUT (FORMAT csv))"</span>;
<a href=#852 id=852 data-nosnippet>852</a> <span class="kw">let </span>result =
<a href=#853 id=853 data-nosnippet>853</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#854 id=854 data-nosnippet>854</a>
<a href=#855 id=855 data-nosnippet>855</a> <span class="macro">assert!</span>(result.is_err());
<a href=#856 id=856 data-nosnippet>856</a> }
<a href=#857 id=857 data-nosnippet>857</a>}
</code></pre></div></section></main></body></html>
File diff suppressed because it is too large Load Diff
+619
View File
@@ -0,0 +1,619 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/create_parser/json.rs`."><title>json.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../../" data-static-root-path="../../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../../static.files/src-script-813739b1.js"></script><script defer src="../../../../src-files.js"></script><script defer src="../../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/create_parser/</div>json.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>datatypes::extension::json::JSON2_REMAINDER_FIELD_NAME;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>datatypes::json::JSON2_MAX_STRUCTURED_DEPTH;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::{DataType, ExactNumberInfo, ObjectName};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser::dialect::keywords::Keyword;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>sqlparser::parser::Parser;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::ast::Ident;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::error::{InvalidSqlSnafu, <span class="prelude-ty">Result</span>, SyntaxSnafu};
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span><span class="kw">crate</span>::parsers::create_parser::{INVERTED, SKIPPING};
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span><span class="kw">crate</span>::statements::create::{Json2Options, JsonTypeHint};
<a href=#28 id=28 data-nosnippet>28</a>
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">const </span>JSON2_TYPE_NAME: <span class="kw-2">&amp;</span>str = <span class="string">"JSON2"</span>;
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">const </span>MAX_AUTO_EXPANDED_PATHS: <span class="kw-2">&amp;</span>str = <span class="string">"max_auto_expanded_paths"</span>;
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a><span class="doccomment">/// Parses a JSON2 type hint path with the same grammar used by `CREATE TABLE`.
<a href=#33 id=33 data-nosnippet>33</a></span><span class="kw">pub fn </span>parse_json2_type_hint_path(path: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;String&gt;&gt; {
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">let </span>dialect = GreptimeDbDialect {};
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">let </span><span class="kw-2">mut </span>parser = Parser::new(<span class="kw-2">&amp;</span>dialect)
<a href=#36 id=36 data-nosnippet>36</a> .try_with_sql(path)
<a href=#37 id=37 data-nosnippet>37</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#38 id=38 data-nosnippet>38</a> <span class="kw">let </span>path = parse_json2_path(<span class="kw-2">&amp;mut </span>parser)<span class="question-mark">?</span>;
<a href=#39 id=39 data-nosnippet>39</a> <span class="macro">ensure!</span>(
<a href=#40 id=40 data-nosnippet>40</a> parser.peek_token().token == Token::EOF,
<a href=#41 id=41 data-nosnippet>41</a> InvalidSqlSnafu {
<a href=#42 id=42 data-nosnippet>42</a> msg: <span class="macro">format!</span>(
<a href=#43 id=43 data-nosnippet>43</a> <span class="string">"unexpected token '{}' in JSON2 type hint path"</span>,
<a href=#44 id=44 data-nosnippet>44</a> parser.peek_token()
<a href=#45 id=45 data-nosnippet>45</a> )
<a href=#46 id=46 data-nosnippet>46</a> }
<a href=#47 id=47 data-nosnippet>47</a> );
<a href=#48 id=48 data-nosnippet>48</a> <span class="prelude-val">Ok</span>(path)
<a href=#49 id=49 data-nosnippet>49</a>}
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_json2_type_and_options(
<a href=#52 id=52 data-nosnippet>52</a> parser: <span class="kw-2">&amp;mut </span>Parser&lt;<span class="lifetime">'_</span>&gt;,
<a href=#53 id=53 data-nosnippet>53</a>) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="prelude-ty">Option</span>&lt;(DataType, <span class="prelude-ty">Option</span>&lt;Json2Options&gt;)&gt;&gt; {
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">let </span>token = parser.peek_token();
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">let </span>Token::Word(word) = <span class="kw-2">&amp;</span>token.token <span class="kw">else </span>{
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>);
<a href=#57 id=57 data-nosnippet>57</a> };
<a href=#58 id=58 data-nosnippet>58</a>
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">if </span>!word.value.eq_ignore_ascii_case(JSON2_TYPE_NAME) || word.quote_style.is_some() {
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>);
<a href=#61 id=61 data-nosnippet>61</a> }
<a href=#62 id=62 data-nosnippet>62</a>
<a href=#63 id=63 data-nosnippet>63</a> parser.next_token();
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">let </span>data_type = DataType::Custom(ObjectName::from(<span class="macro">vec!</span>[Ident::new(JSON2_TYPE_NAME)]), <span class="macro">vec!</span>[]);
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">let </span>options = <span class="kw">if </span>parser.consume_token(<span class="kw-2">&amp;</span>Token::LParen) {
<a href=#66 id=66 data-nosnippet>66</a> parse_json2_options(parser)<span class="question-mark">?
<a href=#67 id=67 data-nosnippet>67</a> </span>} <span class="kw">else </span>{
<a href=#68 id=68 data-nosnippet>68</a> <span class="prelude-val">None
<a href=#69 id=69 data-nosnippet>69</a> </span>};
<a href=#70 id=70 data-nosnippet>70</a>
<a href=#71 id=71 data-nosnippet>71</a> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>((data_type, options)))
<a href=#72 id=72 data-nosnippet>72</a>}
<a href=#73 id=73 data-nosnippet>73</a>
<a href=#74 id=74 data-nosnippet>74</a><span class="kw">fn </span>parse_json2_options(parser: <span class="kw-2">&amp;mut </span>Parser&lt;<span class="lifetime">'_</span>&gt;) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="prelude-ty">Option</span>&lt;Json2Options&gt;&gt; {
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">if </span>parser.consume_token(<span class="kw-2">&amp;</span>Token::RParen) {
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>);
<a href=#77 id=77 data-nosnippet>77</a> }
<a href=#78 id=78 data-nosnippet>78</a>
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw">let </span><span class="kw-2">mut </span>max_auto_expanded_paths = <span class="prelude-val">None</span>;
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">let </span><span class="kw-2">mut </span>type_hints = Vec::new();
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">loop </span>{
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">let </span>token = parser.peek_token();
<a href=#83 id=83 data-nosnippet>83</a> <span class="kw">let </span>is_max_auto_expanded_paths = <span class="macro">matches!</span>(
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw-2">&amp;</span>token.token,
<a href=#85 id=85 data-nosnippet>85</a> Token::Word(word)
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">if </span>word.quote_style.is_none()
<a href=#87 id=87 data-nosnippet>87</a> &amp;&amp; word.value.eq_ignore_ascii_case(MAX_AUTO_EXPANDED_PATHS)
<a href=#88 id=88 data-nosnippet>88</a> );
<a href=#89 id=89 data-nosnippet>89</a> <span class="kw">if </span>is_max_auto_expanded_paths {
<a href=#90 id=90 data-nosnippet>90</a> parser.next_token();
<a href=#91 id=91 data-nosnippet>91</a> <span class="macro">ensure!</span>(
<a href=#92 id=92 data-nosnippet>92</a> max_auto_expanded_paths.is_none(),
<a href=#93 id=93 data-nosnippet>93</a> InvalidSqlSnafu {
<a href=#94 id=94 data-nosnippet>94</a> msg: <span class="macro">format!</span>(<span class="string">"duplicated JSON2 option '{MAX_AUTO_EXPANDED_PATHS}'"</span>)
<a href=#95 id=95 data-nosnippet>95</a> }
<a href=#96 id=96 data-nosnippet>96</a> );
<a href=#97 id=97 data-nosnippet>97</a> parser.expect_token(<span class="kw-2">&amp;</span>Token::Eq).context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#98 id=98 data-nosnippet>98</a>
<a href=#99 id=99 data-nosnippet>99</a> <span class="kw">let </span>token = parser.next_token();
<a href=#100 id=100 data-nosnippet>100</a> <span class="kw">let </span>Token::Number(value, <span class="kw">_</span>) = token.token <span class="kw">else </span>{
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">return </span>InvalidSqlSnafu {
<a href=#102 id=102 data-nosnippet>102</a> msg: <span class="macro">format!</span>(
<a href=#103 id=103 data-nosnippet>103</a> <span class="string">"JSON2 option '{MAX_AUTO_EXPANDED_PATHS}' expects a non-negative integer"
<a href=#104 id=104 data-nosnippet>104</a> </span>),
<a href=#105 id=105 data-nosnippet>105</a> }
<a href=#106 id=106 data-nosnippet>106</a> .fail();
<a href=#107 id=107 data-nosnippet>107</a> };
<a href=#108 id=108 data-nosnippet>108</a> max_auto_expanded_paths = <span class="prelude-val">Some</span>(value.parse::&lt;u32&gt;().map_err(|<span class="kw">_</span>| {
<a href=#109 id=109 data-nosnippet>109</a> InvalidSqlSnafu {
<a href=#110 id=110 data-nosnippet>110</a> msg: <span class="macro">format!</span>(
<a href=#111 id=111 data-nosnippet>111</a> <span class="string">"JSON2 option '{MAX_AUTO_EXPANDED_PATHS}' expects a non-negative integer"
<a href=#112 id=112 data-nosnippet>112</a> </span>),
<a href=#113 id=113 data-nosnippet>113</a> }
<a href=#114 id=114 data-nosnippet>114</a> .build()
<a href=#115 id=115 data-nosnippet>115</a> })<span class="question-mark">?</span>);
<a href=#116 id=116 data-nosnippet>116</a> } <span class="kw">else </span>{
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">let </span>hint = parse_json2_type_hint(parser)<span class="question-mark">?</span>;
<a href=#118 id=118 data-nosnippet>118</a> ensure_no_path_conflict(<span class="kw-2">&amp;</span>type_hints, <span class="kw-2">&amp;</span>hint.path)<span class="question-mark">?</span>;
<a href=#119 id=119 data-nosnippet>119</a> type_hints.push(hint);
<a href=#120 id=120 data-nosnippet>120</a> }
<a href=#121 id=121 data-nosnippet>121</a>
<a href=#122 id=122 data-nosnippet>122</a> <span class="kw">if </span>parser.consume_token(<span class="kw-2">&amp;</span>Token::Comma) {
<a href=#123 id=123 data-nosnippet>123</a> <span class="kw">if </span>parser.consume_token(<span class="kw-2">&amp;</span>Token::RParen) {
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">break</span>;
<a href=#125 id=125 data-nosnippet>125</a> }
<a href=#126 id=126 data-nosnippet>126</a> } <span class="kw">else </span>{
<a href=#127 id=127 data-nosnippet>127</a> parser.expect_token(<span class="kw-2">&amp;</span>Token::RParen).context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">break</span>;
<a href=#129 id=129 data-nosnippet>129</a> }
<a href=#130 id=130 data-nosnippet>130</a> }
<a href=#131 id=131 data-nosnippet>131</a>
<a href=#132 id=132 data-nosnippet>132</a> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(Json2Options {
<a href=#133 id=133 data-nosnippet>133</a> max_auto_expanded_paths,
<a href=#134 id=134 data-nosnippet>134</a> type_hints,
<a href=#135 id=135 data-nosnippet>135</a> }))
<a href=#136 id=136 data-nosnippet>136</a>}
<a href=#137 id=137 data-nosnippet>137</a>
<a href=#138 id=138 data-nosnippet>138</a><span class="kw">fn </span>parse_json2_type_hint(parser: <span class="kw-2">&amp;mut </span>Parser&lt;<span class="lifetime">'_</span>&gt;) -&gt; <span class="prelude-ty">Result</span>&lt;JsonTypeHint&gt; {
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw">let </span>path = parse_json2_path(parser)<span class="question-mark">?</span>;
<a href=#140 id=140 data-nosnippet>140</a> <span class="macro">ensure!</span>(
<a href=#141 id=141 data-nosnippet>141</a> path.first().is_none_or(|x| x != JSON2_REMAINDER_FIELD_NAME),
<a href=#142 id=142 data-nosnippet>142</a> InvalidSqlSnafu {
<a href=#143 id=143 data-nosnippet>143</a> msg: <span class="macro">format!</span>(
<a href=#144 id=144 data-nosnippet>144</a> <span class="string">"JSON2 type hint path cannot be rooted at reserved field '{JSON2_REMAINDER_FIELD_NAME}'"
<a href=#145 id=145 data-nosnippet>145</a> </span>)
<a href=#146 id=146 data-nosnippet>146</a> }
<a href=#147 id=147 data-nosnippet>147</a> );
<a href=#148 id=148 data-nosnippet>148</a> <span class="macro">ensure!</span>(
<a href=#149 id=149 data-nosnippet>149</a> path.len() &lt;= JSON2_MAX_STRUCTURED_DEPTH,
<a href=#150 id=150 data-nosnippet>150</a> InvalidSqlSnafu {
<a href=#151 id=151 data-nosnippet>151</a> msg: <span class="macro">format!</span>(
<a href=#152 id=152 data-nosnippet>152</a> <span class="string">"JSON2 type hint path cannot exceed {JSON2_MAX_STRUCTURED_DEPTH} segments"
<a href=#153 id=153 data-nosnippet>153</a> </span>),
<a href=#154 id=154 data-nosnippet>154</a> }
<a href=#155 id=155 data-nosnippet>155</a> );
<a href=#156 id=156 data-nosnippet>156</a> <span class="kw">let </span>data_type = parser.parse_data_type().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#157 id=157 data-nosnippet>157</a> <span class="kw">let </span>data_type = validate_json2_type_hint_type(data_type)<span class="question-mark">?</span>;
<a href=#158 id=158 data-nosnippet>158</a>
<a href=#159 id=159 data-nosnippet>159</a> <span class="kw">let </span><span class="kw-2">mut </span>inverted_index = <span class="bool-val">false</span>;
<a href=#160 id=160 data-nosnippet>160</a>
<a href=#161 id=161 data-nosnippet>161</a> <span class="kw">loop </span>{
<a href=#162 id=162 data-nosnippet>162</a> <span class="kw">if </span>parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::NOT, Keyword::NULL])
<a href=#163 id=163 data-nosnippet>163</a> || parser.parse_keyword(Keyword::NULL)
<a href=#164 id=164 data-nosnippet>164</a> {
<a href=#165 id=165 data-nosnippet>165</a> <span class="kw">return </span>InvalidSqlSnafu {
<a href=#166 id=166 data-nosnippet>166</a> msg: <span class="string">"JSON2 type hint NULL/NOT NULL is not supported; hinted fields are always nullable"
<a href=#167 id=167 data-nosnippet>167</a> </span>.to_string(),
<a href=#168 id=168 data-nosnippet>168</a> }
<a href=#169 id=169 data-nosnippet>169</a> .fail();
<a href=#170 id=170 data-nosnippet>170</a> } <span class="kw">else if </span>parser.parse_keyword(Keyword::DEFAULT) {
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">return </span>InvalidSqlSnafu {
<a href=#172 id=172 data-nosnippet>172</a> msg: <span class="string">"JSON2 type hint DEFAULT is not supported"</span>.to_string(),
<a href=#173 id=173 data-nosnippet>173</a> }
<a href=#174 id=174 data-nosnippet>174</a> .fail();
<a href=#175 id=175 data-nosnippet>175</a> } <span class="kw">else if let </span>Token::Word(word) = parser.peek_token().token
<a href=#176 id=176 data-nosnippet>176</a> &amp;&amp; word.value.eq_ignore_ascii_case(INVERTED)
<a href=#177 id=177 data-nosnippet>177</a> {
<a href=#178 id=178 data-nosnippet>178</a> parser.next_token();
<a href=#179 id=179 data-nosnippet>179</a> <span class="macro">ensure!</span>(
<a href=#180 id=180 data-nosnippet>180</a> parser.parse_keyword(Keyword::INDEX),
<a href=#181 id=181 data-nosnippet>181</a> InvalidSqlSnafu {
<a href=#182 id=182 data-nosnippet>182</a> msg: <span class="macro">format!</span>(
<a href=#183 id=183 data-nosnippet>183</a> <span class="string">"expect INDEX after INVERTED keyword for JSON2 type hint '{}'"</span>,
<a href=#184 id=184 data-nosnippet>184</a> path.join(<span class="string">"."</span>)
<a href=#185 id=185 data-nosnippet>185</a> )
<a href=#186 id=186 data-nosnippet>186</a> }
<a href=#187 id=187 data-nosnippet>187</a> );
<a href=#188 id=188 data-nosnippet>188</a> <span class="macro">ensure!</span>(
<a href=#189 id=189 data-nosnippet>189</a> !inverted_index,
<a href=#190 id=190 data-nosnippet>190</a> InvalidSqlSnafu {
<a href=#191 id=191 data-nosnippet>191</a> msg: <span class="macro">format!</span>(
<a href=#192 id=192 data-nosnippet>192</a> <span class="string">"duplicated INVERTED INDEX option for JSON2 type hint '{}'"</span>,
<a href=#193 id=193 data-nosnippet>193</a> path.join(<span class="string">"."</span>)
<a href=#194 id=194 data-nosnippet>194</a> )
<a href=#195 id=195 data-nosnippet>195</a> }
<a href=#196 id=196 data-nosnippet>196</a> );
<a href=#197 id=197 data-nosnippet>197</a> inverted_index = <span class="bool-val">true</span>;
<a href=#198 id=198 data-nosnippet>198</a> } <span class="kw">else if let </span>Token::Word(word) = parser.peek_token().token
<a href=#199 id=199 data-nosnippet>199</a> &amp;&amp; word.value.eq_ignore_ascii_case(SKIPPING)
<a href=#200 id=200 data-nosnippet>200</a> {
<a href=#201 id=201 data-nosnippet>201</a> <span class="kw">return </span>InvalidSqlSnafu {
<a href=#202 id=202 data-nosnippet>202</a> msg: <span class="string">"JSON2 type hint SKIPPING INDEX is not supported yet"</span>.to_string(),
<a href=#203 id=203 data-nosnippet>203</a> }
<a href=#204 id=204 data-nosnippet>204</a> .fail();
<a href=#205 id=205 data-nosnippet>205</a> } <span class="kw">else if </span><span class="macro">matches!</span>(parser.peek_token().token, Token::Comma | Token::RParen) {
<a href=#206 id=206 data-nosnippet>206</a> <span class="kw">break</span>;
<a href=#207 id=207 data-nosnippet>207</a> } <span class="kw">else </span>{
<a href=#208 id=208 data-nosnippet>208</a> <span class="kw">return </span>parser
<a href=#209 id=209 data-nosnippet>209</a> .expected(<span class="string">"JSON2 type hint option"</span>, parser.peek_token())
<a href=#210 id=210 data-nosnippet>210</a> .context(SyntaxSnafu);
<a href=#211 id=211 data-nosnippet>211</a> }
<a href=#212 id=212 data-nosnippet>212</a> }
<a href=#213 id=213 data-nosnippet>213</a>
<a href=#214 id=214 data-nosnippet>214</a> <span class="prelude-val">Ok</span>(JsonTypeHint {
<a href=#215 id=215 data-nosnippet>215</a> path,
<a href=#216 id=216 data-nosnippet>216</a> data_type,
<a href=#217 id=217 data-nosnippet>217</a> inverted_index,
<a href=#218 id=218 data-nosnippet>218</a> })
<a href=#219 id=219 data-nosnippet>219</a>}
<a href=#220 id=220 data-nosnippet>220</a>
<a href=#221 id=221 data-nosnippet>221</a><span class="kw">fn </span>parse_json2_path(parser: <span class="kw-2">&amp;mut </span>Parser&lt;<span class="lifetime">'_</span>&gt;) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;String&gt;&gt; {
<a href=#222 id=222 data-nosnippet>222</a> <span class="kw">let </span>first = parser.parse_identifier().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#223 id=223 data-nosnippet>223</a> <span class="kw">let </span><span class="kw-2">mut </span>path = <span class="macro">vec!</span>[first.value];
<a href=#224 id=224 data-nosnippet>224</a>
<a href=#225 id=225 data-nosnippet>225</a> <span class="kw">while </span>parser.consume_token(<span class="kw-2">&amp;</span>Token::Period) {
<a href=#226 id=226 data-nosnippet>226</a> <span class="kw">let </span>segment = parser.parse_identifier().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#227 id=227 data-nosnippet>227</a> path.push(segment.value);
<a href=#228 id=228 data-nosnippet>228</a> }
<a href=#229 id=229 data-nosnippet>229</a>
<a href=#230 id=230 data-nosnippet>230</a> <span class="macro">ensure!</span>(
<a href=#231 id=231 data-nosnippet>231</a> !path.iter().any(|segment| segment.is_empty()),
<a href=#232 id=232 data-nosnippet>232</a> InvalidSqlSnafu {
<a href=#233 id=233 data-nosnippet>233</a> msg: <span class="string">"JSON2 type hint path segment cannot be empty"</span>.to_string(),
<a href=#234 id=234 data-nosnippet>234</a> }
<a href=#235 id=235 data-nosnippet>235</a> );
<a href=#236 id=236 data-nosnippet>236</a>
<a href=#237 id=237 data-nosnippet>237</a> <span class="prelude-val">Ok</span>(path)
<a href=#238 id=238 data-nosnippet>238</a>}
<a href=#239 id=239 data-nosnippet>239</a>
<a href=#240 id=240 data-nosnippet>240</a><span class="kw">fn </span>validate_json2_type_hint_type(data_type: DataType) -&gt; <span class="prelude-ty">Result</span>&lt;DataType&gt; {
<a href=#241 id=241 data-nosnippet>241</a> <span class="kw">match </span>data_type {
<a href=#242 id=242 data-nosnippet>242</a> DataType::Int64
<a href=#243 id=243 data-nosnippet>243</a> | DataType::UInt64
<a href=#244 id=244 data-nosnippet>244</a> | DataType::Float64
<a href=#245 id=245 data-nosnippet>245</a> | DataType::String(<span class="prelude-val">None</span>)
<a href=#246 id=246 data-nosnippet>246</a> | DataType::BigInt(<span class="prelude-val">None</span>)
<a href=#247 id=247 data-nosnippet>247</a> | DataType::BigIntUnsigned(<span class="prelude-val">None</span>)
<a href=#248 id=248 data-nosnippet>248</a> | DataType::Double(ExactNumberInfo::None)
<a href=#249 id=249 data-nosnippet>249</a> | DataType::Boolean =&gt; <span class="prelude-val">Ok</span>(data_type),
<a href=#250 id=250 data-nosnippet>250</a> <span class="kw">_ </span>=&gt; InvalidSqlSnafu {
<a href=#251 id=251 data-nosnippet>251</a> msg: <span class="macro">format!</span>(
<a href=#252 id=252 data-nosnippet>252</a> <span class="string">"unsupported JSON2 type hint data type: {data_type}; supported types: STRING, BIGINT, BIGINT UNSIGNED, DOUBLE, BOOLEAN; supported aliases: INT64, UINT64, FLOAT64"
<a href=#253 id=253 data-nosnippet>253</a> </span>),
<a href=#254 id=254 data-nosnippet>254</a> }
<a href=#255 id=255 data-nosnippet>255</a> .fail(),
<a href=#256 id=256 data-nosnippet>256</a> }
<a href=#257 id=257 data-nosnippet>257</a>}
<a href=#258 id=258 data-nosnippet>258</a>
<a href=#259 id=259 data-nosnippet>259</a><span class="kw">fn </span>ensure_no_path_conflict(hints: <span class="kw-2">&amp;</span>[JsonTypeHint], path: <span class="kw-2">&amp;</span>[String]) -&gt; <span class="prelude-ty">Result</span>&lt;()&gt; {
<a href=#260 id=260 data-nosnippet>260</a> <span class="kw">for </span>hint <span class="kw">in </span>hints {
<a href=#261 id=261 data-nosnippet>261</a> <span class="macro">ensure!</span>(
<a href=#262 id=262 data-nosnippet>262</a> hint.path != path,
<a href=#263 id=263 data-nosnippet>263</a> InvalidSqlSnafu {
<a href=#264 id=264 data-nosnippet>264</a> msg: <span class="macro">format!</span>(<span class="string">"duplicated JSON2 type hint path '{}'"</span>, path.join(<span class="string">"."</span>))
<a href=#265 id=265 data-nosnippet>265</a> }
<a href=#266 id=266 data-nosnippet>266</a> );
<a href=#267 id=267 data-nosnippet>267</a> <span class="macro">ensure!</span>(
<a href=#268 id=268 data-nosnippet>268</a> !hint.path.starts_with(path) &amp;&amp; !path.starts_with(<span class="kw-2">&amp;</span>hint.path),
<a href=#269 id=269 data-nosnippet>269</a> InvalidSqlSnafu {
<a href=#270 id=270 data-nosnippet>270</a> msg: <span class="macro">format!</span>(
<a href=#271 id=271 data-nosnippet>271</a> <span class="string">"JSON2 type hint path '{}' conflicts with '{}'"</span>,
<a href=#272 id=272 data-nosnippet>272</a> path.join(<span class="string">"."</span>),
<a href=#273 id=273 data-nosnippet>273</a> hint.path.join(<span class="string">"."</span>)
<a href=#274 id=274 data-nosnippet>274</a> )
<a href=#275 id=275 data-nosnippet>275</a> }
<a href=#276 id=276 data-nosnippet>276</a> );
<a href=#277 id=277 data-nosnippet>277</a> }
<a href=#278 id=278 data-nosnippet>278</a> <span class="prelude-val">Ok</span>(())
<a href=#279 id=279 data-nosnippet>279</a>}
<a href=#280 id=280 data-nosnippet>280</a>
<a href=#281 id=281 data-nosnippet>281</a><span class="attr">#[cfg(test)]
<a href=#282 id=282 data-nosnippet>282</a></span><span class="kw">mod </span>tests {
<a href=#283 id=283 data-nosnippet>283</a> <span class="kw">use </span>sqlparser::ast::{DataType, ExactNumberInfo};
<a href=#284 id=284 data-nosnippet>284</a>
<a href=#285 id=285 data-nosnippet>285</a> <span class="kw">use </span><span class="kw">super</span>::parse_json2_type_hint_path;
<a href=#286 id=286 data-nosnippet>286</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#287 id=287 data-nosnippet>287</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#288 id=288 data-nosnippet>288</a> <span class="kw">use </span><span class="kw">crate</span>::statements::create::Column;
<a href=#289 id=289 data-nosnippet>289</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#290 id=290 data-nosnippet>290</a>
<a href=#291 id=291 data-nosnippet>291</a> <span class="kw">fn </span>parse_json2_column(sql: <span class="kw-2">&amp;</span>str) -&gt; Column {
<a href=#292 id=292 data-nosnippet>292</a> <span class="kw">let </span>Statement::CreateTable(<span class="kw-2">mut </span>create_table) =
<a href=#293 id=293 data-nosnippet>293</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#294 id=294 data-nosnippet>294</a> .unwrap()
<a href=#295 id=295 data-nosnippet>295</a> .remove(<span class="number">0</span>)
<a href=#296 id=296 data-nosnippet>296</a> <span class="kw">else </span>{
<a href=#297 id=297 data-nosnippet>297</a> <span class="macro">unreachable!</span>()
<a href=#298 id=298 data-nosnippet>298</a> };
<a href=#299 id=299 data-nosnippet>299</a>
<a href=#300 id=300 data-nosnippet>300</a> create_table.columns.remove(<span class="number">0</span>)
<a href=#301 id=301 data-nosnippet>301</a> }
<a href=#302 id=302 data-nosnippet>302</a>
<a href=#303 id=303 data-nosnippet>303</a> <span class="attr">#[test]
<a href=#304 id=304 data-nosnippet>304</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_path() {
<a href=#305 id=305 data-nosnippet>305</a> <span class="macro">assert_eq!</span>(
<a href=#306 id=306 data-nosnippet>306</a> parse_json2_type_hint_path(<span class="string">r#"attrs."http.status_code""#</span>).unwrap(),
<a href=#307 id=307 data-nosnippet>307</a> <span class="macro">vec!</span>[<span class="string">"attrs"</span>, <span class="string">"http.status_code"</span>]
<a href=#308 id=308 data-nosnippet>308</a> );
<a href=#309 id=309 data-nosnippet>309</a> <span class="macro">assert!</span>(parse_json2_type_hint_path(<span class="string">"user.id trailing"</span>).is_err());
<a href=#310 id=310 data-nosnippet>310</a> }
<a href=#311 id=311 data-nosnippet>311</a>
<a href=#312 id=312 data-nosnippet>312</a> <span class="attr">#[test]
<a href=#313 id=313 data-nosnippet>313</a> </span><span class="kw">fn </span>test_parse_json2_type_hints() {
<a href=#314 id=314 data-nosnippet>314</a> <span class="kw">let </span>column = parse_json2_column(
<a href=#315 id=315 data-nosnippet>315</a> <span class="string">r#"
<a href=#316 id=316 data-nosnippet>316</a>CREATE TABLE traces (
<a href=#317 id=317 data-nosnippet>317</a> log_json_data JSON2 (
<a href=#318 id=318 data-nosnippet>318</a> "service.name" STRING INVERTED INDEX,
<a href=#319 id=319 data-nosnippet>319</a> http.method STRING,
<a href=#320 id=320 data-nosnippet>320</a> status_code BIGINT,
<a href=#321 id=321 data-nosnippet>321</a> comment STRING,
<a href=#322 id=322 data-nosnippet>322</a> ),
<a href=#323 id=323 data-nosnippet>323</a> ts TIMESTAMP TIME INDEX,
<a href=#324 id=324 data-nosnippet>324</a>)"#</span>,
<a href=#325 id=325 data-nosnippet>325</a> );
<a href=#326 id=326 data-nosnippet>326</a>
<a href=#327 id=327 data-nosnippet>327</a> <span class="macro">assert!</span>(<span class="macro">matches!</span>(
<a href=#328 id=328 data-nosnippet>328</a> column.column_def.data_type,
<a href=#329 id=329 data-nosnippet>329</a> DataType::Custom(<span class="kw">_</span>, <span class="kw">_</span>)
<a href=#330 id=330 data-nosnippet>330</a> ));
<a href=#331 id=331 data-nosnippet>331</a> <span class="kw">let </span>hints = column.extensions.json2_options.unwrap().type_hints;
<a href=#332 id=332 data-nosnippet>332</a> <span class="macro">assert_eq!</span>(hints.len(), <span class="number">4</span>);
<a href=#333 id=333 data-nosnippet>333</a>
<a href=#334 id=334 data-nosnippet>334</a> <span class="macro">assert_eq!</span>(hints[<span class="number">0</span>].path, <span class="macro">vec!</span>[<span class="string">"service.name"</span>]);
<a href=#335 id=335 data-nosnippet>335</a> <span class="macro">assert_eq!</span>(hints[<span class="number">0</span>].data_type, DataType::String(<span class="prelude-val">None</span>));
<a href=#336 id=336 data-nosnippet>336</a> <span class="macro">assert!</span>(hints[<span class="number">0</span>].inverted_index);
<a href=#337 id=337 data-nosnippet>337</a>
<a href=#338 id=338 data-nosnippet>338</a> <span class="macro">assert_eq!</span>(hints[<span class="number">1</span>].path, <span class="macro">vec!</span>[<span class="string">"http"</span>, <span class="string">"method"</span>]);
<a href=#339 id=339 data-nosnippet>339</a> <span class="macro">assert_eq!</span>(hints[<span class="number">1</span>].data_type, DataType::String(<span class="prelude-val">None</span>));
<a href=#340 id=340 data-nosnippet>340</a> <span class="macro">assert!</span>(!hints[<span class="number">1</span>].inverted_index);
<a href=#341 id=341 data-nosnippet>341</a>
<a href=#342 id=342 data-nosnippet>342</a> <span class="macro">assert_eq!</span>(hints[<span class="number">2</span>].path, <span class="macro">vec!</span>[<span class="string">"status_code"</span>]);
<a href=#343 id=343 data-nosnippet>343</a> <span class="macro">assert_eq!</span>(hints[<span class="number">2</span>].data_type, DataType::BigInt(<span class="prelude-val">None</span>));
<a href=#344 id=344 data-nosnippet>344</a>
<a href=#345 id=345 data-nosnippet>345</a> <span class="macro">assert_eq!</span>(hints[<span class="number">3</span>].path, <span class="macro">vec!</span>[<span class="string">"comment"</span>]);
<a href=#346 id=346 data-nosnippet>346</a> <span class="macro">assert_eq!</span>(hints[<span class="number">3</span>].data_type, DataType::String(<span class="prelude-val">None</span>));
<a href=#347 id=347 data-nosnippet>347</a> }
<a href=#348 id=348 data-nosnippet>348</a>
<a href=#349 id=349 data-nosnippet>349</a> <span class="attr">#[test]
<a href=#350 id=350 data-nosnippet>350</a> </span><span class="kw">fn </span>test_parse_json2_max_auto_expanded_paths() {
<a href=#351 id=351 data-nosnippet>351</a> <span class="kw">let </span>column = parse_json2_column(
<a href=#352 id=352 data-nosnippet>352</a> <span class="string">r#"
<a href=#353 id=353 data-nosnippet>353</a>CREATE TABLE traces (
<a href=#354 id=354 data-nosnippet>354</a> log_json_data JSON2 (
<a href=#355 id=355 data-nosnippet>355</a> http.method STRING,
<a href=#356 id=356 data-nosnippet>356</a> max_auto_expanded_paths = 0
<a href=#357 id=357 data-nosnippet>357</a> ),
<a href=#358 id=358 data-nosnippet>358</a> ts TIMESTAMP TIME INDEX,
<a href=#359 id=359 data-nosnippet>359</a>)"#</span>,
<a href=#360 id=360 data-nosnippet>360</a> );
<a href=#361 id=361 data-nosnippet>361</a>
<a href=#362 id=362 data-nosnippet>362</a> <span class="kw">let </span>options = column.extensions.json2_options.unwrap();
<a href=#363 id=363 data-nosnippet>363</a> <span class="macro">assert_eq!</span>(options.max_auto_expanded_paths, <span class="prelude-val">Some</span>(<span class="number">0</span>));
<a href=#364 id=364 data-nosnippet>364</a> <span class="macro">assert_eq!</span>(options.type_hints.len(), <span class="number">1</span>);
<a href=#365 id=365 data-nosnippet>365</a>
<a href=#366 id=366 data-nosnippet>366</a> <span class="kw">let </span>empty = parse_json2_column(
<a href=#367 id=367 data-nosnippet>367</a> <span class="string">r#"
<a href=#368 id=368 data-nosnippet>368</a>CREATE TABLE traces (
<a href=#369 id=369 data-nosnippet>369</a> log_json_data JSON2 (),
<a href=#370 id=370 data-nosnippet>370</a> ts TIMESTAMP TIME INDEX,
<a href=#371 id=371 data-nosnippet>371</a>)"#</span>,
<a href=#372 id=372 data-nosnippet>372</a> );
<a href=#373 id=373 data-nosnippet>373</a> <span class="macro">assert!</span>(empty.extensions.json2_options.is_none());
<a href=#374 id=374 data-nosnippet>374</a>
<a href=#375 id=375 data-nosnippet>375</a> <span class="kw">let </span>quoted = parse_json2_column(
<a href=#376 id=376 data-nosnippet>376</a> <span class="string">r#"
<a href=#377 id=377 data-nosnippet>377</a>CREATE TABLE traces (
<a href=#378 id=378 data-nosnippet>378</a> log_json_data JSON2 (
<a href=#379 id=379 data-nosnippet>379</a> "max_auto_expanded_paths" STRING,
<a href=#380 id=380 data-nosnippet>380</a> nested."!__remainder__!" STRING
<a href=#381 id=381 data-nosnippet>381</a> ),
<a href=#382 id=382 data-nosnippet>382</a> ts TIMESTAMP TIME INDEX,
<a href=#383 id=383 data-nosnippet>383</a>)"#</span>,
<a href=#384 id=384 data-nosnippet>384</a> );
<a href=#385 id=385 data-nosnippet>385</a> <span class="kw">let </span>options = quoted.extensions.json2_options.unwrap();
<a href=#386 id=386 data-nosnippet>386</a> <span class="macro">assert_eq!</span>(options.max_auto_expanded_paths, <span class="prelude-val">None</span>);
<a href=#387 id=387 data-nosnippet>387</a> <span class="macro">assert_eq!</span>(options.type_hints.len(), <span class="number">2</span>);
<a href=#388 id=388 data-nosnippet>388</a> }
<a href=#389 id=389 data-nosnippet>389</a>
<a href=#390 id=390 data-nosnippet>390</a> <span class="attr">#[test]
<a href=#391 id=391 data-nosnippet>391</a> </span><span class="kw">fn </span>test_parse_json2_max_auto_expanded_paths_rejects_invalid_options() {
<a href=#392 id=392 data-nosnippet>392</a> <span class="kw">for </span>options <span class="kw">in </span>[
<a href=#393 id=393 data-nosnippet>393</a> <span class="string">"max_auto_expanded_paths = 0, max_auto_expanded_paths = 1"</span>,
<a href=#394 id=394 data-nosnippet>394</a> <span class="string">"max_auto_expanded_paths = -1"</span>,
<a href=#395 id=395 data-nosnippet>395</a> <span class="string">"max_auto_expanded_paths = 1.5"</span>,
<a href=#396 id=396 data-nosnippet>396</a> <span class="string">"max_auto_expanded_paths = 4294967296"</span>,
<a href=#397 id=397 data-nosnippet>397</a> <span class="string">r#""!__remainder__!".value STRING"#</span>,
<a href=#398 id=398 data-nosnippet>398</a> ] {
<a href=#399 id=399 data-nosnippet>399</a> <span class="kw">let </span>sql = <span class="macro">format!</span>(
<a href=#400 id=400 data-nosnippet>400</a> <span class="string">"CREATE TABLE traces (log_json_data JSON2 ({options}), ts TIMESTAMP TIME INDEX)"
<a href=#401 id=401 data-nosnippet>401</a> </span>);
<a href=#402 id=402 data-nosnippet>402</a> <span class="macro">assert!</span>(
<a href=#403 id=403 data-nosnippet>403</a> ParserContext::create_with_dialect(
<a href=#404 id=404 data-nosnippet>404</a> <span class="kw-2">&amp;</span>sql,
<a href=#405 id=405 data-nosnippet>405</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#406 id=406 data-nosnippet>406</a> ParseOptions::default()
<a href=#407 id=407 data-nosnippet>407</a> )
<a href=#408 id=408 data-nosnippet>408</a> .is_err(),
<a href=#409 id=409 data-nosnippet>409</a> <span class="string">"{options}"
<a href=#410 id=410 data-nosnippet>410</a> </span>);
<a href=#411 id=411 data-nosnippet>411</a> }
<a href=#412 id=412 data-nosnippet>412</a> }
<a href=#413 id=413 data-nosnippet>413</a>
<a href=#414 id=414 data-nosnippet>414</a> <span class="attr">#[test]
<a href=#415 id=415 data-nosnippet>415</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_defaults_to_nullable() {
<a href=#416 id=416 data-nosnippet>416</a> <span class="kw">let </span>column = parse_json2_column(
<a href=#417 id=417 data-nosnippet>417</a> <span class="string">r#"
<a href=#418 id=418 data-nosnippet>418</a>CREATE TABLE traces (
<a href=#419 id=419 data-nosnippet>419</a> log_json_data JSON2 (http.method STRING),
<a href=#420 id=420 data-nosnippet>420</a> ts TIMESTAMP TIME INDEX,
<a href=#421 id=421 data-nosnippet>421</a>)"#</span>,
<a href=#422 id=422 data-nosnippet>422</a> );
<a href=#423 id=423 data-nosnippet>423</a>
<a href=#424 id=424 data-nosnippet>424</a> <span class="kw">let </span>hints = column.extensions.json2_options.unwrap().type_hints;
<a href=#425 id=425 data-nosnippet>425</a> <span class="macro">assert_eq!</span>(hints.len(), <span class="number">1</span>);
<a href=#426 id=426 data-nosnippet>426</a> <span class="macro">assert_eq!</span>(hints[<span class="number">0</span>].data_type, DataType::String(<span class="prelude-val">None</span>));
<a href=#427 id=427 data-nosnippet>427</a> }
<a href=#428 id=428 data-nosnippet>428</a>
<a href=#429 id=429 data-nosnippet>429</a> <span class="attr">#[test]
<a href=#430 id=430 data-nosnippet>430</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_quoted_path_segments() {
<a href=#431 id=431 data-nosnippet>431</a> <span class="kw">let </span>column = parse_json2_column(
<a href=#432 id=432 data-nosnippet>432</a> <span class="string">r#"
<a href=#433 id=433 data-nosnippet>433</a>CREATE TABLE traces (
<a href=#434 id=434 data-nosnippet>434</a> log_json_data JSON2 (
<a href=#435 id=435 data-nosnippet>435</a> "a".b STRING,
<a href=#436 id=436 data-nosnippet>436</a> "x"."y" STRING,
<a href=#437 id=437 data-nosnippet>437</a> "a.b"."c" STRING,
<a href=#438 id=438 data-nosnippet>438</a> a."b.c" STRING
<a href=#439 id=439 data-nosnippet>439</a> ),
<a href=#440 id=440 data-nosnippet>440</a> ts TIMESTAMP TIME INDEX,
<a href=#441 id=441 data-nosnippet>441</a>)"#</span>,
<a href=#442 id=442 data-nosnippet>442</a> );
<a href=#443 id=443 data-nosnippet>443</a>
<a href=#444 id=444 data-nosnippet>444</a> <span class="kw">let </span>hints = column.extensions.json2_options.unwrap().type_hints;
<a href=#445 id=445 data-nosnippet>445</a> <span class="macro">assert_eq!</span>(hints.len(), <span class="number">4</span>);
<a href=#446 id=446 data-nosnippet>446</a> <span class="macro">assert_eq!</span>(hints[<span class="number">0</span>].path, <span class="macro">vec!</span>[<span class="string">"a"</span>, <span class="string">"b"</span>]);
<a href=#447 id=447 data-nosnippet>447</a> <span class="macro">assert_eq!</span>(hints[<span class="number">1</span>].path, <span class="macro">vec!</span>[<span class="string">"x"</span>, <span class="string">"y"</span>]);
<a href=#448 id=448 data-nosnippet>448</a> <span class="macro">assert_eq!</span>(hints[<span class="number">2</span>].path, <span class="macro">vec!</span>[<span class="string">"a.b"</span>, <span class="string">"c"</span>]);
<a href=#449 id=449 data-nosnippet>449</a> <span class="macro">assert_eq!</span>(hints[<span class="number">3</span>].path, <span class="macro">vec!</span>[<span class="string">"a"</span>, <span class="string">"b.c"</span>]);
<a href=#450 id=450 data-nosnippet>450</a> }
<a href=#451 id=451 data-nosnippet>451</a>
<a href=#452 id=452 data-nosnippet>452</a> <span class="attr">#[test]
<a href=#453 id=453 data-nosnippet>453</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_supported_types() {
<a href=#454 id=454 data-nosnippet>454</a> <span class="kw">for </span>(sql_type, expected) <span class="kw">in </span>[
<a href=#455 id=455 data-nosnippet>455</a> (<span class="string">"STRING"</span>, DataType::String(<span class="prelude-val">None</span>)),
<a href=#456 id=456 data-nosnippet>456</a> (<span class="string">"BIGINT"</span>, DataType::BigInt(<span class="prelude-val">None</span>)),
<a href=#457 id=457 data-nosnippet>457</a> (<span class="string">"BIGINT UNSIGNED"</span>, DataType::BigIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#458 id=458 data-nosnippet>458</a> (<span class="string">"DOUBLE"</span>, DataType::Double(ExactNumberInfo::None)),
<a href=#459 id=459 data-nosnippet>459</a> (<span class="string">"BOOLEAN"</span>, DataType::Boolean),
<a href=#460 id=460 data-nosnippet>460</a> (<span class="string">"INT64"</span>, DataType::Int64),
<a href=#461 id=461 data-nosnippet>461</a> (<span class="string">"UINT64"</span>, DataType::UInt64),
<a href=#462 id=462 data-nosnippet>462</a> (<span class="string">"FLOAT64"</span>, DataType::Float64),
<a href=#463 id=463 data-nosnippet>463</a> ] {
<a href=#464 id=464 data-nosnippet>464</a> <span class="kw">for </span>sql_type <span class="kw">in </span>[sql_type.to_string(), sql_type.to_lowercase()] {
<a href=#465 id=465 data-nosnippet>465</a> <span class="kw">let </span>column = parse_json2_column(<span class="kw-2">&amp;</span><span class="macro">format!</span>(
<a href=#466 id=466 data-nosnippet>466</a> <span class="string">"CREATE TABLE traces (j JSON2 (value {sql_type}), ts TIMESTAMP TIME INDEX)"
<a href=#467 id=467 data-nosnippet>467</a> </span>));
<a href=#468 id=468 data-nosnippet>468</a> <span class="kw">let </span>options = column.extensions.json2_options.unwrap();
<a href=#469 id=469 data-nosnippet>469</a> <span class="kw">let </span>settings = options.build_json_settings().unwrap();
<a href=#470 id=470 data-nosnippet>470</a> <span class="macro">assert_eq!</span>(settings.type_hints().len(), <span class="number">1</span>);
<a href=#471 id=471 data-nosnippet>471</a> <span class="kw">let </span>hints = options.type_hints;
<a href=#472 id=472 data-nosnippet>472</a> <span class="macro">assert_eq!</span>(hints[<span class="number">0</span>].data_type, expected);
<a href=#473 id=473 data-nosnippet>473</a> }
<a href=#474 id=474 data-nosnippet>474</a> }
<a href=#475 id=475 data-nosnippet>475</a> }
<a href=#476 id=476 data-nosnippet>476</a>
<a href=#477 id=477 data-nosnippet>477</a> <span class="attr">#[test]
<a href=#478 id=478 data-nosnippet>478</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_rejects_unsupported_types() {
<a href=#479 id=479 data-nosnippet>479</a> <span class="kw">for </span>sql_type <span class="kw">in </span>[
<a href=#480 id=480 data-nosnippet>480</a> <span class="string">"INT2"</span>,
<a href=#481 id=481 data-nosnippet>481</a> <span class="string">"INT4"</span>,
<a href=#482 id=482 data-nosnippet>482</a> <span class="string">"INT8"</span>,
<a href=#483 id=483 data-nosnippet>483</a> <span class="string">"INT16"</span>,
<a href=#484 id=484 data-nosnippet>484</a> <span class="string">"INT32"</span>,
<a href=#485 id=485 data-nosnippet>485</a> <span class="string">"TINYINT"</span>,
<a href=#486 id=486 data-nosnippet>486</a> <span class="string">"SMALLINT"</span>,
<a href=#487 id=487 data-nosnippet>487</a> <span class="string">"INT"</span>,
<a href=#488 id=488 data-nosnippet>488</a> <span class="string">"INTEGER"</span>,
<a href=#489 id=489 data-nosnippet>489</a> <span class="string">"UINT8"</span>,
<a href=#490 id=490 data-nosnippet>490</a> <span class="string">"UINT16"</span>,
<a href=#491 id=491 data-nosnippet>491</a> <span class="string">"UINT32"</span>,
<a href=#492 id=492 data-nosnippet>492</a> <span class="string">"TINYINT UNSIGNED"</span>,
<a href=#493 id=493 data-nosnippet>493</a> <span class="string">"SMALLINT UNSIGNED"</span>,
<a href=#494 id=494 data-nosnippet>494</a> <span class="string">"INT UNSIGNED"</span>,
<a href=#495 id=495 data-nosnippet>495</a> <span class="string">"FLOAT"</span>,
<a href=#496 id=496 data-nosnippet>496</a> <span class="string">"REAL"</span>,
<a href=#497 id=497 data-nosnippet>497</a> <span class="string">"FLOAT4"</span>,
<a href=#498 id=498 data-nosnippet>498</a> <span class="string">"FLOAT8"</span>,
<a href=#499 id=499 data-nosnippet>499</a> <span class="string">"FLOAT32"</span>,
<a href=#500 id=500 data-nosnippet>500</a> <span class="string">"BOOL"</span>,
<a href=#501 id=501 data-nosnippet>501</a> <span class="string">"TEXT"</span>,
<a href=#502 id=502 data-nosnippet>502</a> <span class="string">"VARCHAR(10)"</span>,
<a href=#503 id=503 data-nosnippet>503</a> <span class="string">"CHAR(10)"</span>,
<a href=#504 id=504 data-nosnippet>504</a> <span class="string">"TIMESTAMP"</span>,
<a href=#505 id=505 data-nosnippet>505</a> <span class="string">"DECIMAL(10, 2)"</span>,
<a href=#506 id=506 data-nosnippet>506</a> <span class="string">"STRING(10)"</span>,
<a href=#507 id=507 data-nosnippet>507</a> <span class="string">"BIGINT(10)"</span>,
<a href=#508 id=508 data-nosnippet>508</a> ] {
<a href=#509 id=509 data-nosnippet>509</a> <span class="kw">for </span>sql <span class="kw">in </span>[
<a href=#510 id=510 data-nosnippet>510</a> <span class="macro">format!</span>(
<a href=#511 id=511 data-nosnippet>511</a> <span class="string">"CREATE TABLE traces (j JSON2 (value {sql_type}), ts TIMESTAMP TIME INDEX)"
<a href=#512 id=512 data-nosnippet>512</a> </span>),
<a href=#513 id=513 data-nosnippet>513</a> <span class="macro">format!</span>(<span class="string">"ALTER TABLE traces MODIFY COLUMN j JSON2 (value {sql_type})"</span>),
<a href=#514 id=514 data-nosnippet>514</a> ] {
<a href=#515 id=515 data-nosnippet>515</a> <span class="kw">let </span>err = ParserContext::create_with_dialect(
<a href=#516 id=516 data-nosnippet>516</a> <span class="kw-2">&amp;</span>sql,
<a href=#517 id=517 data-nosnippet>517</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#518 id=518 data-nosnippet>518</a> ParseOptions::default(),
<a href=#519 id=519 data-nosnippet>519</a> )
<a href=#520 id=520 data-nosnippet>520</a> .unwrap_err();
<a href=#521 id=521 data-nosnippet>521</a> <span class="macro">assert!</span>(
<a href=#522 id=522 data-nosnippet>522</a> err.to_string().contains(
<a href=#523 id=523 data-nosnippet>523</a> <span class="string">"supported types: STRING, BIGINT, BIGINT UNSIGNED, DOUBLE, BOOLEAN; supported aliases: INT64, UINT64, FLOAT64"
<a href=#524 id=524 data-nosnippet>524</a> </span>),
<a href=#525 id=525 data-nosnippet>525</a> <span class="string">"{sql}: {err}"
<a href=#526 id=526 data-nosnippet>526</a> </span>);
<a href=#527 id=527 data-nosnippet>527</a> }
<a href=#528 id=528 data-nosnippet>528</a> }
<a href=#529 id=529 data-nosnippet>529</a> }
<a href=#530 id=530 data-nosnippet>530</a>
<a href=#531 id=531 data-nosnippet>531</a> <span class="attr">#[test]
<a href=#532 id=532 data-nosnippet>532</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_rejects_default() {
<a href=#533 id=533 data-nosnippet>533</a> <span class="kw">for </span>default <span class="kw">in </span>[<span class="string">"-5"</span>, <span class="string">"abs(-1)"</span>] {
<a href=#534 id=534 data-nosnippet>534</a> <span class="kw">let </span>sql = <span class="macro">format!</span>(
<a href=#535 id=535 data-nosnippet>535</a> <span class="string">"CREATE TABLE traces (log_json_data JSON2 (status_code BIGINT DEFAULT {default}), ts TIMESTAMP TIME INDEX)"
<a href=#536 id=536 data-nosnippet>536</a> </span>);
<a href=#537 id=537 data-nosnippet>537</a> <span class="kw">let </span>err = ParserContext::create_with_dialect(
<a href=#538 id=538 data-nosnippet>538</a> <span class="kw-2">&amp;</span>sql,
<a href=#539 id=539 data-nosnippet>539</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#540 id=540 data-nosnippet>540</a> ParseOptions::default(),
<a href=#541 id=541 data-nosnippet>541</a> )
<a href=#542 id=542 data-nosnippet>542</a> .unwrap_err();
<a href=#543 id=543 data-nosnippet>543</a> <span class="macro">assert!</span>(err.to_string().contains(<span class="string">"DEFAULT is not supported"</span>));
<a href=#544 id=544 data-nosnippet>544</a> }
<a href=#545 id=545 data-nosnippet>545</a> }
<a href=#546 id=546 data-nosnippet>546</a>
<a href=#547 id=547 data-nosnippet>547</a> <span class="attr">#[test]
<a href=#548 id=548 data-nosnippet>548</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_rejects_duplicate_path() {
<a href=#549 id=549 data-nosnippet>549</a> <span class="kw">let </span>result = ParserContext::create_with_dialect(
<a href=#550 id=550 data-nosnippet>550</a> <span class="string">r#"
<a href=#551 id=551 data-nosnippet>551</a>CREATE TABLE traces (
<a href=#552 id=552 data-nosnippet>552</a> log_json_data JSON2 (a.b STRING, a.b BIGINT),
<a href=#553 id=553 data-nosnippet>553</a> ts TIMESTAMP TIME INDEX,
<a href=#554 id=554 data-nosnippet>554</a>)"#</span>,
<a href=#555 id=555 data-nosnippet>555</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#556 id=556 data-nosnippet>556</a> ParseOptions::default(),
<a href=#557 id=557 data-nosnippet>557</a> );
<a href=#558 id=558 data-nosnippet>558</a>
<a href=#559 id=559 data-nosnippet>559</a> <span class="macro">assert!</span>(result.is_err());
<a href=#560 id=560 data-nosnippet>560</a> <span class="macro">assert!</span>(result.unwrap_err().to_string().contains(<span class="string">"duplicated"</span>));
<a href=#561 id=561 data-nosnippet>561</a> }
<a href=#562 id=562 data-nosnippet>562</a>
<a href=#563 id=563 data-nosnippet>563</a> <span class="attr">#[test]
<a href=#564 id=564 data-nosnippet>564</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_rejects_parent_child_path() {
<a href=#565 id=565 data-nosnippet>565</a> <span class="kw">let </span>result = ParserContext::create_with_dialect(
<a href=#566 id=566 data-nosnippet>566</a> <span class="string">r#"
<a href=#567 id=567 data-nosnippet>567</a>CREATE TABLE traces (
<a href=#568 id=568 data-nosnippet>568</a> log_json_data JSON2 (a STRING, a.b BIGINT),
<a href=#569 id=569 data-nosnippet>569</a> ts TIMESTAMP TIME INDEX,
<a href=#570 id=570 data-nosnippet>570</a>)"#</span>,
<a href=#571 id=571 data-nosnippet>571</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#572 id=572 data-nosnippet>572</a> ParseOptions::default(),
<a href=#573 id=573 data-nosnippet>573</a> );
<a href=#574 id=574 data-nosnippet>574</a>
<a href=#575 id=575 data-nosnippet>575</a> <span class="macro">assert!</span>(result.is_err());
<a href=#576 id=576 data-nosnippet>576</a> <span class="macro">assert!</span>(result.unwrap_err().to_string().contains(<span class="string">"conflicts"</span>));
<a href=#577 id=577 data-nosnippet>577</a> }
<a href=#578 id=578 data-nosnippet>578</a>
<a href=#579 id=579 data-nosnippet>579</a> <span class="attr">#[test]
<a href=#580 id=580 data-nosnippet>580</a> </span><span class="kw">fn </span>test_parse_json2_type_hint_rejects_nullability() {
<a href=#581 id=581 data-nosnippet>581</a> <span class="kw">for </span>sql <span class="kw">in </span>[
<a href=#582 id=582 data-nosnippet>582</a> <span class="string">r#"
<a href=#583 id=583 data-nosnippet>583</a>CREATE TABLE traces (
<a href=#584 id=584 data-nosnippet>584</a> log_json_data JSON2 (a STRING NULL NULL),
<a href=#585 id=585 data-nosnippet>585</a> ts TIMESTAMP TIME INDEX,
<a href=#586 id=586 data-nosnippet>586</a>)"#</span>,
<a href=#587 id=587 data-nosnippet>587</a> <span class="string">r#"
<a href=#588 id=588 data-nosnippet>588</a>CREATE TABLE traces (
<a href=#589 id=589 data-nosnippet>589</a> log_json_data JSON2 (a STRING NOT NULL NOT NULL),
<a href=#590 id=590 data-nosnippet>590</a> ts TIMESTAMP TIME INDEX,
<a href=#591 id=591 data-nosnippet>591</a>)"#</span>,
<a href=#592 id=592 data-nosnippet>592</a> <span class="string">r#"
<a href=#593 id=593 data-nosnippet>593</a>CREATE TABLE traces (
<a href=#594 id=594 data-nosnippet>594</a> log_json_data JSON2 (a STRING NOT NULL NULL),
<a href=#595 id=595 data-nosnippet>595</a> ts TIMESTAMP TIME INDEX,
<a href=#596 id=596 data-nosnippet>596</a>)"#</span>,
<a href=#597 id=597 data-nosnippet>597</a> <span class="string">r#"
<a href=#598 id=598 data-nosnippet>598</a>CREATE TABLE traces (
<a href=#599 id=599 data-nosnippet>599</a> log_json_data JSON2 (a STRING NULL NOT NULL),
<a href=#600 id=600 data-nosnippet>600</a> ts TIMESTAMP TIME INDEX,
<a href=#601 id=601 data-nosnippet>601</a>)"#</span>,
<a href=#602 id=602 data-nosnippet>602</a> ] {
<a href=#603 id=603 data-nosnippet>603</a> <span class="kw">let </span>result = ParserContext::create_with_dialect(
<a href=#604 id=604 data-nosnippet>604</a> sql,
<a href=#605 id=605 data-nosnippet>605</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#606 id=606 data-nosnippet>606</a> ParseOptions::default(),
<a href=#607 id=607 data-nosnippet>607</a> );
<a href=#608 id=608 data-nosnippet>608</a>
<a href=#609 id=609 data-nosnippet>609</a> <span class="macro">assert!</span>(result.is_err());
<a href=#610 id=610 data-nosnippet>610</a> <span class="macro">assert!</span>(
<a href=#611 id=611 data-nosnippet>611</a> result
<a href=#612 id=612 data-nosnippet>612</a> .unwrap_err()
<a href=#613 id=613 data-nosnippet>613</a> .to_string()
<a href=#614 id=614 data-nosnippet>614</a> .contains(<span class="string">"NULL/NOT NULL is not supported"</span>)
<a href=#615 id=615 data-nosnippet>615</a> );
<a href=#616 id=616 data-nosnippet>616</a> }
<a href=#617 id=617 data-nosnippet>617</a> }
<a href=#618 id=618 data-nosnippet>618</a>}
</code></pre></div></section></main></body></html>
+160
View File
@@ -0,0 +1,160 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/cursor_parser.rs`."><title>cursor_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>cursor_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::cursor::{CloseCursor, DeclareCursor, FetchCursor};
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#25 id=25 data-nosnippet>25</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_declare_cursor(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.expect_keyword(Keyword::DECLARE);
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let </span>cursor_name = <span class="self">self
<a href=#28 id=28 data-nosnippet>28</a> </span>.parser
<a href=#29 id=29 data-nosnippet>29</a> .parse_object_name(<span class="bool-val">false</span>)
<a href=#30 id=30 data-nosnippet>30</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">let _ </span>= <span class="self">self
<a href=#32 id=32 data-nosnippet>32</a> </span>.parser
<a href=#33 id=33 data-nosnippet>33</a> .expect_keywords(<span class="kw-2">&amp;</span>[Keyword::CURSOR, Keyword::FOR]);
<a href=#34 id=34 data-nosnippet>34</a>
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">let </span><span class="kw-2">mut </span>is_select = <span class="bool-val">false</span>;
<a href=#36 id=36 data-nosnippet>36</a> <span class="kw">if let </span>Token::Word(w) = <span class="self">self</span>.parser.peek_token().token {
<a href=#37 id=37 data-nosnippet>37</a> <span class="kw">match </span>w.keyword {
<a href=#38 id=38 data-nosnippet>38</a> Keyword::SELECT | Keyword::WITH =&gt; {
<a href=#39 id=39 data-nosnippet>39</a> is_select = <span class="bool-val">true</span>;
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a> <span class="kw">_ </span>=&gt; {}
<a href=#42 id=42 data-nosnippet>42</a> }
<a href=#43 id=43 data-nosnippet>43</a> };
<a href=#44 id=44 data-nosnippet>44</a> <span class="macro">ensure!</span>(
<a href=#45 id=45 data-nosnippet>45</a> is_select,
<a href=#46 id=46 data-nosnippet>46</a> error::InvalidSqlSnafu {
<a href=#47 id=47 data-nosnippet>47</a> msg: <span class="string">"Expect select query in cursor statement"</span>.to_string(),
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a> );
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">let </span>query_stmt = <span class="self">self</span>.parse_query()<span class="question-mark">?</span>;
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">match </span>query_stmt {
<a href=#53 id=53 data-nosnippet>53</a> Statement::Query(query) =&gt; <span class="prelude-val">Ok</span>(Statement::DeclareCursor(DeclareCursor {
<a href=#54 id=54 data-nosnippet>54</a> cursor_name: ParserContext::canonicalize_object_name(cursor_name)<span class="question-mark">?</span>,
<a href=#55 id=55 data-nosnippet>55</a> query,
<a href=#56 id=56 data-nosnippet>56</a> })),
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">_ </span>=&gt; error::InvalidSqlSnafu {
<a href=#58 id=58 data-nosnippet>58</a> msg: <span class="macro">format!</span>(<span class="string">"Expect query, found {}"</span>, query_stmt),
<a href=#59 id=59 data-nosnippet>59</a> }
<a href=#60 id=60 data-nosnippet>60</a> .fail(),
<a href=#61 id=61 data-nosnippet>61</a> }
<a href=#62 id=62 data-nosnippet>62</a> }
<a href=#63 id=63 data-nosnippet>63</a>
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_fetch_cursor(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.expect_keyword(Keyword::FETCH);
<a href=#66 id=66 data-nosnippet>66</a>
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">let </span>fetch_size = <span class="self">self
<a href=#68 id=68 data-nosnippet>68</a> </span>.parser
<a href=#69 id=69 data-nosnippet>69</a> .parse_literal_uint()
<a href=#70 id=70 data-nosnippet>70</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">let _ </span>= <span class="self">self
<a href=#72 id=72 data-nosnippet>72</a> </span>.parser
<a href=#73 id=73 data-nosnippet>73</a> .parse_one_of_keywords(<span class="kw-2">&amp;</span>[Keyword::FROM, Keyword::IN]);
<a href=#74 id=74 data-nosnippet>74</a>
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">let </span>cursor_name = <span class="self">self
<a href=#76 id=76 data-nosnippet>76</a> </span>.parser
<a href=#77 id=77 data-nosnippet>77</a> .parse_object_name(<span class="bool-val">false</span>)
<a href=#78 id=78 data-nosnippet>78</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#79 id=79 data-nosnippet>79</a>
<a href=#80 id=80 data-nosnippet>80</a> <span class="prelude-val">Ok</span>(Statement::FetchCursor(FetchCursor {
<a href=#81 id=81 data-nosnippet>81</a> cursor_name: ParserContext::canonicalize_object_name(cursor_name)<span class="question-mark">?</span>,
<a href=#82 id=82 data-nosnippet>82</a> fetch_size,
<a href=#83 id=83 data-nosnippet>83</a> }))
<a href=#84 id=84 data-nosnippet>84</a> }
<a href=#85 id=85 data-nosnippet>85</a>
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_close_cursor(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#87 id=87 data-nosnippet>87</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.expect_keyword(Keyword::CLOSE);
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">let </span>cursor_name = <span class="self">self
<a href=#89 id=89 data-nosnippet>89</a> </span>.parser
<a href=#90 id=90 data-nosnippet>90</a> .parse_object_name(<span class="bool-val">false</span>)
<a href=#91 id=91 data-nosnippet>91</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#92 id=92 data-nosnippet>92</a>
<a href=#93 id=93 data-nosnippet>93</a> <span class="prelude-val">Ok</span>(Statement::CloseCursor(CloseCursor {
<a href=#94 id=94 data-nosnippet>94</a> cursor_name: ParserContext::canonicalize_object_name(cursor_name)<span class="question-mark">?</span>,
<a href=#95 id=95 data-nosnippet>95</a> }))
<a href=#96 id=96 data-nosnippet>96</a> }
<a href=#97 id=97 data-nosnippet>97</a>}
<a href=#98 id=98 data-nosnippet>98</a>
<a href=#99 id=99 data-nosnippet>99</a><span class="attr">#[cfg(test)]
<a href=#100 id=100 data-nosnippet>100</a></span><span class="kw">mod </span>tests {
<a href=#101 id=101 data-nosnippet>101</a>
<a href=#102 id=102 data-nosnippet>102</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#103 id=103 data-nosnippet>103</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#105 id=105 data-nosnippet>105</a>
<a href=#106 id=106 data-nosnippet>106</a> <span class="attr">#[test]
<a href=#107 id=107 data-nosnippet>107</a> </span><span class="kw">fn </span>test_parse_declare_cursor() {
<a href=#108 id=108 data-nosnippet>108</a> <span class="kw">let </span>sql = <span class="string">"DECLARE c1 CURSOR FOR\nSELECT * FROM numbers"</span>;
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw">let </span>result =
<a href=#110 id=110 data-nosnippet>110</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#111 id=111 data-nosnippet>111</a> .unwrap();
<a href=#112 id=112 data-nosnippet>112</a>
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">if let </span>Statement::DeclareCursor(dc) = <span class="kw-2">&amp;</span>result[<span class="number">0</span>] {
<a href=#114 id=114 data-nosnippet>114</a> <span class="macro">assert_eq!</span>(<span class="string">"c1"</span>, dc.cursor_name.to_string());
<a href=#115 id=115 data-nosnippet>115</a> <span class="macro">assert_eq!</span>(
<a href=#116 id=116 data-nosnippet>116</a> <span class="string">"DECLARE c1 CURSOR FOR SELECT * FROM numbers"</span>,
<a href=#117 id=117 data-nosnippet>117</a> dc.to_string()
<a href=#118 id=118 data-nosnippet>118</a> );
<a href=#119 id=119 data-nosnippet>119</a> } <span class="kw">else </span>{
<a href=#120 id=120 data-nosnippet>120</a> <span class="macro">panic!</span>(<span class="string">"Unexpected statement"</span>);
<a href=#121 id=121 data-nosnippet>121</a> }
<a href=#122 id=122 data-nosnippet>122</a>
<a href=#123 id=123 data-nosnippet>123</a> <span class="kw">let </span>sql = <span class="string">"DECLARE c1 CURSOR FOR\nINSERT INTO numbers VALUES (1);"</span>;
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">let </span>result =
<a href=#125 id=125 data-nosnippet>125</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#126 id=126 data-nosnippet>126</a> <span class="macro">assert!</span>(result.is_err());
<a href=#127 id=127 data-nosnippet>127</a> }
<a href=#128 id=128 data-nosnippet>128</a>
<a href=#129 id=129 data-nosnippet>129</a> <span class="attr">#[test]
<a href=#130 id=130 data-nosnippet>130</a> </span><span class="kw">fn </span>test_parese_fetch_cursor() {
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">let </span>sql = <span class="string">"FETCH 1000 FROM c1"</span>;
<a href=#132 id=132 data-nosnippet>132</a> <span class="kw">let </span>result =
<a href=#133 id=133 data-nosnippet>133</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#134 id=134 data-nosnippet>134</a> .unwrap();
<a href=#135 id=135 data-nosnippet>135</a>
<a href=#136 id=136 data-nosnippet>136</a> <span class="kw">if let </span>Statement::FetchCursor(fc) = <span class="kw-2">&amp;</span>result[<span class="number">0</span>] {
<a href=#137 id=137 data-nosnippet>137</a> <span class="macro">assert_eq!</span>(<span class="string">"c1"</span>, fc.cursor_name.to_string());
<a href=#138 id=138 data-nosnippet>138</a> <span class="macro">assert_eq!</span>(<span class="string">"1000"</span>, fc.fetch_size.to_string());
<a href=#139 id=139 data-nosnippet>139</a> <span class="macro">assert_eq!</span>(sql, fc.to_string());
<a href=#140 id=140 data-nosnippet>140</a> } <span class="kw">else </span>{
<a href=#141 id=141 data-nosnippet>141</a> <span class="macro">panic!</span>(<span class="string">"Unexpected statement"</span>)
<a href=#142 id=142 data-nosnippet>142</a> }
<a href=#143 id=143 data-nosnippet>143</a> }
<a href=#144 id=144 data-nosnippet>144</a>
<a href=#145 id=145 data-nosnippet>145</a> <span class="attr">#[test]
<a href=#146 id=146 data-nosnippet>146</a> </span><span class="kw">fn </span>test_close_fetch_cursor() {
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw">let </span>sql = <span class="string">"CLOSE c1"</span>;
<a href=#148 id=148 data-nosnippet>148</a> <span class="kw">let </span>result =
<a href=#149 id=149 data-nosnippet>149</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#150 id=150 data-nosnippet>150</a> .unwrap();
<a href=#151 id=151 data-nosnippet>151</a>
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">if let </span>Statement::CloseCursor(cc) = <span class="kw-2">&amp;</span>result[<span class="number">0</span>] {
<a href=#153 id=153 data-nosnippet>153</a> <span class="macro">assert_eq!</span>(<span class="string">"c1"</span>, cc.cursor_name.to_string());
<a href=#154 id=154 data-nosnippet>154</a> <span class="macro">assert_eq!</span>(sql, cc.to_string());
<a href=#155 id=155 data-nosnippet>155</a> } <span class="kw">else </span>{
<a href=#156 id=156 data-nosnippet>156</a> <span class="macro">panic!</span>(<span class="string">"Unexpected statement"</span>)
<a href=#157 id=157 data-nosnippet>157</a> }
<a href=#158 id=158 data-nosnippet>158</a> }
<a href=#159 id=159 data-nosnippet>159</a>}
</code></pre></div></section></main></body></html>
+31
View File
@@ -0,0 +1,31 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/deallocate_parser.rs`."><title>deallocate_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>deallocate_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="prelude-ty">Result</span>, SyntaxSnafu};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#22 id=22 data-nosnippet>22</a> <span class="doccomment">/// Parses MySQL style 'PREPARE stmt_name' into a stmt_name string.
<a href=#23 id=23 data-nosnippet>23</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_deallocate(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;String&gt; {
<a href=#24 id=24 data-nosnippet>24</a> <span class="self">self</span>.parser
<a href=#25 id=25 data-nosnippet>25</a> .expect_keyword(Keyword::DEALLOCATE)
<a href=#26 id=26 data-nosnippet>26</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let </span>stmt_name = <span class="self">self</span>.parser.parse_identifier().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#28 id=28 data-nosnippet>28</a> <span class="prelude-val">Ok</span>(stmt_name.value)
<a href=#29 id=29 data-nosnippet>29</a> }
<a href=#30 id=30 data-nosnippet>30</a>}
</code></pre></div></section></main></body></html>
+70
View File
@@ -0,0 +1,70 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/delete_parser.rs`."><title>delete_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>delete_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::Statement <span class="kw">as </span>SpStatement;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::statements::delete::Delete;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// DELETE statement parser implementation
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#25 id=25 data-nosnippet>25</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_delete(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">let </span>token = <span class="self">self</span>.parser.next_token();
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let </span>spstatement = <span class="self">self
<a href=#28 id=28 data-nosnippet>28</a> </span>.parser
<a href=#29 id=29 data-nosnippet>29</a> .parse_delete(token)
<a href=#30 id=30 data-nosnippet>30</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">match </span>spstatement {
<a href=#33 id=33 data-nosnippet>33</a> SpStatement::Delete { .. } =&gt; {
<a href=#34 id=34 data-nosnippet>34</a> <span class="prelude-val">Ok</span>(Statement::Delete(Box::new(Delete { inner: spstatement })))
<a href=#35 id=35 data-nosnippet>35</a> }
<a href=#36 id=36 data-nosnippet>36</a> unexp =&gt; error::UnsupportedSnafu {
<a href=#37 id=37 data-nosnippet>37</a> keyword: unexp.to_string(),
<a href=#38 id=38 data-nosnippet>38</a> }
<a href=#39 id=39 data-nosnippet>39</a> .fail(),
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a> }
<a href=#42 id=42 data-nosnippet>42</a>}
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a><span class="attr">#[cfg(test)]
<a href=#45 id=45 data-nosnippet>45</a></span><span class="kw">mod </span>tests {
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">use </span>std::assert_matches;
<a href=#47 id=47 data-nosnippet>47</a>
<a href=#48 id=48 data-nosnippet>48</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#51 id=51 data-nosnippet>51</a>
<a href=#52 id=52 data-nosnippet>52</a> <span class="attr">#[test]
<a href=#53 id=53 data-nosnippet>53</a> </span><span class="kw">pub fn </span>test_parse_insert() {
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">let </span>sql = <span class="string">r"delete from my_table where k1 = xxx and k2 = xxx and timestamp = xxx;"</span>;
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">let </span>result =
<a href=#56 id=56 data-nosnippet>56</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#57 id=57 data-nosnippet>57</a> .unwrap();
<a href=#58 id=58 data-nosnippet>58</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#59 id=59 data-nosnippet>59</a> <span class="macro">assert_matches!</span>(result[<span class="number">0</span>], Statement::Delete { .. })
<a href=#60 id=60 data-nosnippet>60</a> }
<a href=#61 id=61 data-nosnippet>61</a>
<a href=#62 id=62 data-nosnippet>62</a> <span class="attr">#[test]
<a href=#63 id=63 data-nosnippet>63</a> </span><span class="kw">pub fn </span>test_parse_invalid_insert() {
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">let </span>sql = <span class="string">r"delete my_table where "</span>; <span class="comment">// intentionally a bad sql
<a href=#65 id=65 data-nosnippet>65</a> </span><span class="kw">let </span>result =
<a href=#66 id=66 data-nosnippet>66</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#67 id=67 data-nosnippet>67</a> <span class="macro">assert!</span>(result.is_err(), <span class="string">"result is: {result:?}"</span>);
<a href=#68 id=68 data-nosnippet>68</a> }
<a href=#69 id=69 data-nosnippet>69</a>}
</code></pre></div></section></main></body></html>
+82
View File
@@ -0,0 +1,82 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/describe_parser.rs`."><title>describe_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>describe_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, InvalidTableNameSnafu, <span class="prelude-ty">Result</span>};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::statements::describe::DescribeTable;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// DESCRIBE statement parser implementation
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#25 id=25 data-nosnippet>25</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_describe(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">if </span><span class="self">self</span>.matches_keyword(Keyword::TABLE) {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#28 id=28 data-nosnippet>28</a> }
<a href=#29 id=29 data-nosnippet>29</a> <span class="self">self</span>.parse_describe_table()
<a href=#30 id=30 data-nosnippet>30</a> }
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">fn </span>parse_describe_table(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">let </span>raw_table_idents =
<a href=#34 id=34 data-nosnippet>34</a> <span class="self">self</span>.parse_object_name()
<a href=#35 id=35 data-nosnippet>35</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#36 id=36 data-nosnippet>36</a> expected: <span class="string">"a table name"</span>,
<a href=#37 id=37 data-nosnippet>37</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#38 id=38 data-nosnippet>38</a> })<span class="question-mark">?</span>;
<a href=#39 id=39 data-nosnippet>39</a> <span class="kw">let </span>table_idents = <span class="self">Self</span>::canonicalize_object_name(raw_table_idents)<span class="question-mark">?</span>;
<a href=#40 id=40 data-nosnippet>40</a> <span class="macro">ensure!</span>(
<a href=#41 id=41 data-nosnippet>41</a> !table_idents.<span class="number">0</span>.is_empty(),
<a href=#42 id=42 data-nosnippet>42</a> InvalidTableNameSnafu {
<a href=#43 id=43 data-nosnippet>43</a> name: table_idents.to_string(),
<a href=#44 id=44 data-nosnippet>44</a> }
<a href=#45 id=45 data-nosnippet>45</a> );
<a href=#46 id=46 data-nosnippet>46</a> <span class="prelude-val">Ok</span>(Statement::DescribeTable(DescribeTable::new(table_idents)))
<a href=#47 id=47 data-nosnippet>47</a> }
<a href=#48 id=48 data-nosnippet>48</a>}
<a href=#49 id=49 data-nosnippet>49</a>
<a href=#50 id=50 data-nosnippet>50</a><span class="attr">#[cfg(test)]
<a href=#51 id=51 data-nosnippet>51</a></span><span class="kw">mod </span>tests {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">use </span>sqlparser::ast::Expr;
<a href=#53 id=53 data-nosnippet>53</a>
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a> <span class="attr">#[test]
<a href=#59 id=59 data-nosnippet>59</a> </span><span class="kw">fn </span>test_parse_function() {
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">let </span>expr =
<a href=#61 id=61 data-nosnippet>61</a> ParserContext::parse_function(<span class="string">"current_timestamp()"</span>, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap();
<a href=#62 id=62 data-nosnippet>62</a> <span class="macro">assert!</span>(<span class="macro">matches!</span>(expr, Expr::Function(<span class="kw">_</span>)));
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a>
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">fn </span>assert_describe_table(sql: <span class="kw-2">&amp;</span>str) {
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">let </span>stmt =
<a href=#67 id=67 data-nosnippet>67</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#68 id=68 data-nosnippet>68</a> .unwrap()
<a href=#69 id=69 data-nosnippet>69</a> .pop()
<a href=#70 id=70 data-nosnippet>70</a> .unwrap();
<a href=#71 id=71 data-nosnippet>71</a> <span class="macro">assert!</span>(<span class="macro">matches!</span>(stmt, Statement::DescribeTable(<span class="kw">_</span>)))
<a href=#72 id=72 data-nosnippet>72</a> }
<a href=#73 id=73 data-nosnippet>73</a>
<a href=#74 id=74 data-nosnippet>74</a> <span class="attr">#[test]
<a href=#75 id=75 data-nosnippet>75</a> </span><span class="kw">fn </span>test_parse_describe_table() {
<a href=#76 id=76 data-nosnippet>76</a> assert_describe_table(<span class="string">"desc table t;"</span>);
<a href=#77 id=77 data-nosnippet>77</a> assert_describe_table(<span class="string">"describe table t;"</span>);
<a href=#78 id=78 data-nosnippet>78</a> assert_describe_table(<span class="string">"desc t;"</span>);
<a href=#79 id=79 data-nosnippet>79</a> assert_describe_table(<span class="string">"describe t;"</span>);
<a href=#80 id=80 data-nosnippet>80</a> }
<a href=#81 id=81 data-nosnippet>81</a>}
</code></pre></div></section></main></body></html>
+463
View File
@@ -0,0 +1,463 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/drop_parser.rs`."><title>drop_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>drop_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::dialect::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, InvalidFlowNameSnafu, InvalidTableNameSnafu, <span class="prelude-ty">Result</span>};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::parser::{FLOW, ParserContext};
<a href=#21 id=21 data-nosnippet>21</a><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#22 id=22 data-nosnippet>22</a></span><span class="kw">use </span><span class="kw">crate</span>::statements::drop::UndropTable;
<a href=#23 id=23 data-nosnippet>23</a><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">use </span><span class="kw">crate</span>::statements::drop::trigger::DropTrigger;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#27 id=27 data-nosnippet>27</a>
<a href=#28 id=28 data-nosnippet>28</a><span class="doccomment">/// DROP statement parser implementation
<a href=#29 id=29 data-nosnippet>29</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#30 id=30 data-nosnippet>30</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#31 id=31 data-nosnippet>31</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_undrop_table(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">if </span>!<span class="self">self</span>.parser.parse_keyword(Keyword::TABLE) {
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">return </span><span class="self">self</span>.expected(<span class="string">"TABLE"</span>, <span class="self">self</span>.parser.peek_token());
<a href=#35 id=35 data-nosnippet>35</a> }
<a href=#36 id=36 data-nosnippet>36</a>
<a href=#37 id=37 data-nosnippet>37</a> <span class="kw">let </span>raw_table_name = <span class="self">self
<a href=#38 id=38 data-nosnippet>38</a> </span>.parse_object_name()
<a href=#39 id=39 data-nosnippet>39</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#40 id=40 data-nosnippet>40</a> expected: <span class="string">"a table name"</span>,
<a href=#41 id=41 data-nosnippet>41</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#42 id=42 data-nosnippet>42</a> })<span class="question-mark">?</span>;
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw">let </span>table_name = <span class="self">Self</span>::canonicalize_object_name(raw_table_name)<span class="question-mark">?</span>;
<a href=#44 id=44 data-nosnippet>44</a> <span class="macro">ensure!</span>(
<a href=#45 id=45 data-nosnippet>45</a> !table_name.<span class="number">0</span>.is_empty(),
<a href=#46 id=46 data-nosnippet>46</a> InvalidTableNameSnafu {
<a href=#47 id=47 data-nosnippet>47</a> name: table_name.to_string()
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a> );
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a> <span class="prelude-val">Ok</span>(Statement::UndropTable(UndropTable::new(table_name)))
<a href=#52 id=52 data-nosnippet>52</a> }
<a href=#53 id=53 data-nosnippet>53</a>
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">match </span><span class="self">self</span>.parser.peek_token().token {
<a href=#57 id=57 data-nosnippet>57</a> Token::Word(w) =&gt; <span class="kw">match </span>w.keyword {
<a href=#58 id=58 data-nosnippet>58</a> Keyword::TABLE =&gt; <span class="self">self</span>.parse_drop_table(),
<a href=#59 id=59 data-nosnippet>59</a> Keyword::VIEW =&gt; <span class="self">self</span>.parse_drop_view(),
<a href=#60 id=60 data-nosnippet>60</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#61 id=61 data-nosnippet>61</a> </span>Keyword::TRIGGER =&gt; <span class="self">self</span>.parse_drop_trigger(),
<a href=#62 id=62 data-nosnippet>62</a> Keyword::SCHEMA | Keyword::DATABASE =&gt; <span class="self">self</span>.parse_drop_database(),
<a href=#63 id=63 data-nosnippet>63</a> Keyword::NoKeyword =&gt; {
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">let </span>uppercase = w.value.to_uppercase();
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">match </span>uppercase.as_str() {
<a href=#66 id=66 data-nosnippet>66</a> FLOW =&gt; <span class="self">self</span>.parse_drop_flow(),
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">_ </span>=&gt; <span class="self">self</span>.unsupported(w.to_string()),
<a href=#68 id=68 data-nosnippet>68</a> }
<a href=#69 id=69 data-nosnippet>69</a> }
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">_ </span>=&gt; <span class="self">self</span>.unsupported(w.to_string()),
<a href=#71 id=71 data-nosnippet>71</a> },
<a href=#72 id=72 data-nosnippet>72</a> unexpected =&gt; <span class="self">self</span>.unsupported(unexpected.to_string()),
<a href=#73 id=73 data-nosnippet>73</a> }
<a href=#74 id=74 data-nosnippet>74</a> }
<a href=#75 id=75 data-nosnippet>75</a>
<a href=#76 id=76 data-nosnippet>76</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#77 id=77 data-nosnippet>77</a> </span><span class="kw">fn </span>parse_drop_trigger(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#78 id=78 data-nosnippet>78</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#79 id=79 data-nosnippet>79</a>
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">let </span>if_exists = <span class="self">self</span>.parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::IF, Keyword::EXISTS]);
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">let </span>raw_trigger_ident =
<a href=#82 id=82 data-nosnippet>82</a> <span class="self">self</span>.parse_object_name()
<a href=#83 id=83 data-nosnippet>83</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#84 id=84 data-nosnippet>84</a> expected: <span class="string">"a trigger name"</span>,
<a href=#85 id=85 data-nosnippet>85</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#86 id=86 data-nosnippet>86</a> })<span class="question-mark">?</span>;
<a href=#87 id=87 data-nosnippet>87</a> <span class="kw">let </span>trigger_ident = <span class="self">Self</span>::canonicalize_object_name(raw_trigger_ident)<span class="question-mark">?</span>;
<a href=#88 id=88 data-nosnippet>88</a> <span class="macro">ensure!</span>(
<a href=#89 id=89 data-nosnippet>89</a> !trigger_ident.<span class="number">0</span>.is_empty(),
<a href=#90 id=90 data-nosnippet>90</a> error::InvalidTriggerNameSnafu {
<a href=#91 id=91 data-nosnippet>91</a> name: trigger_ident.to_string()
<a href=#92 id=92 data-nosnippet>92</a> }
<a href=#93 id=93 data-nosnippet>93</a> );
<a href=#94 id=94 data-nosnippet>94</a>
<a href=#95 id=95 data-nosnippet>95</a> <span class="prelude-val">Ok</span>(Statement::DropTrigger(DropTrigger::new(
<a href=#96 id=96 data-nosnippet>96</a> trigger_ident,
<a href=#97 id=97 data-nosnippet>97</a> if_exists,
<a href=#98 id=98 data-nosnippet>98</a> )))
<a href=#99 id=99 data-nosnippet>99</a> }
<a href=#100 id=100 data-nosnippet>100</a>
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">fn </span>parse_drop_view(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#102 id=102 data-nosnippet>102</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#103 id=103 data-nosnippet>103</a>
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">let </span>if_exists = <span class="self">self</span>.parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::IF, Keyword::EXISTS]);
<a href=#105 id=105 data-nosnippet>105</a> <span class="kw">let </span>raw_view_ident = <span class="self">self
<a href=#106 id=106 data-nosnippet>106</a> </span>.parse_object_name()
<a href=#107 id=107 data-nosnippet>107</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#108 id=108 data-nosnippet>108</a> expected: <span class="string">"a view name"</span>,
<a href=#109 id=109 data-nosnippet>109</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#110 id=110 data-nosnippet>110</a> })<span class="question-mark">?</span>;
<a href=#111 id=111 data-nosnippet>111</a> <span class="kw">let </span>view_ident = <span class="self">Self</span>::canonicalize_object_name(raw_view_ident)<span class="question-mark">?</span>;
<a href=#112 id=112 data-nosnippet>112</a> <span class="macro">ensure!</span>(
<a href=#113 id=113 data-nosnippet>113</a> !view_ident.<span class="number">0</span>.is_empty(),
<a href=#114 id=114 data-nosnippet>114</a> InvalidTableNameSnafu {
<a href=#115 id=115 data-nosnippet>115</a> name: view_ident.to_string()
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a> );
<a href=#118 id=118 data-nosnippet>118</a>
<a href=#119 id=119 data-nosnippet>119</a> <span class="prelude-val">Ok</span>(Statement::DropView(DropView {
<a href=#120 id=120 data-nosnippet>120</a> view_name: view_ident,
<a href=#121 id=121 data-nosnippet>121</a> drop_if_exists: if_exists,
<a href=#122 id=122 data-nosnippet>122</a> }))
<a href=#123 id=123 data-nosnippet>123</a> }
<a href=#124 id=124 data-nosnippet>124</a>
<a href=#125 id=125 data-nosnippet>125</a> <span class="kw">fn </span>parse_drop_flow(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#127 id=127 data-nosnippet>127</a>
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">let </span>if_exists = <span class="self">self</span>.parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::IF, Keyword::EXISTS]);
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">let </span>raw_flow_ident = <span class="self">self
<a href=#130 id=130 data-nosnippet>130</a> </span>.parse_object_name()
<a href=#131 id=131 data-nosnippet>131</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#132 id=132 data-nosnippet>132</a> expected: <span class="string">"a flow name"</span>,
<a href=#133 id=133 data-nosnippet>133</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#134 id=134 data-nosnippet>134</a> })<span class="question-mark">?</span>;
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">let </span>flow_ident = <span class="self">Self</span>::canonicalize_object_name(raw_flow_ident)<span class="question-mark">?</span>;
<a href=#136 id=136 data-nosnippet>136</a> <span class="macro">ensure!</span>(
<a href=#137 id=137 data-nosnippet>137</a> !flow_ident.<span class="number">0</span>.is_empty(),
<a href=#138 id=138 data-nosnippet>138</a> InvalidFlowNameSnafu {
<a href=#139 id=139 data-nosnippet>139</a> name: flow_ident.to_string()
<a href=#140 id=140 data-nosnippet>140</a> }
<a href=#141 id=141 data-nosnippet>141</a> );
<a href=#142 id=142 data-nosnippet>142</a>
<a href=#143 id=143 data-nosnippet>143</a> <span class="prelude-val">Ok</span>(Statement::DropFlow(DropFlow::new(flow_ident, if_exists)))
<a href=#144 id=144 data-nosnippet>144</a> }
<a href=#145 id=145 data-nosnippet>145</a>
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">fn </span>parse_drop_table(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#148 id=148 data-nosnippet>148</a>
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw">let </span>if_exists = <span class="self">self</span>.parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::IF, Keyword::EXISTS]);
<a href=#150 id=150 data-nosnippet>150</a> <span class="kw">let </span><span class="kw-2">mut </span>table_names = Vec::with_capacity(<span class="number">1</span>);
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw">loop </span>{
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">let </span>raw_table_ident =
<a href=#153 id=153 data-nosnippet>153</a> <span class="self">self</span>.parse_object_name()
<a href=#154 id=154 data-nosnippet>154</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#155 id=155 data-nosnippet>155</a> expected: <span class="string">"a table name"</span>,
<a href=#156 id=156 data-nosnippet>156</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#157 id=157 data-nosnippet>157</a> })<span class="question-mark">?</span>;
<a href=#158 id=158 data-nosnippet>158</a> <span class="kw">let </span>table_ident = <span class="self">Self</span>::canonicalize_object_name(raw_table_ident)<span class="question-mark">?</span>;
<a href=#159 id=159 data-nosnippet>159</a> <span class="macro">ensure!</span>(
<a href=#160 id=160 data-nosnippet>160</a> !table_ident.<span class="number">0</span>.is_empty(),
<a href=#161 id=161 data-nosnippet>161</a> InvalidTableNameSnafu {
<a href=#162 id=162 data-nosnippet>162</a> name: table_ident.to_string()
<a href=#163 id=163 data-nosnippet>163</a> }
<a href=#164 id=164 data-nosnippet>164</a> );
<a href=#165 id=165 data-nosnippet>165</a> table_names.push(table_ident);
<a href=#166 id=166 data-nosnippet>166</a> <span class="kw">if </span>!<span class="self">self</span>.parser.consume_token(<span class="kw-2">&amp;</span>Token::Comma) {
<a href=#167 id=167 data-nosnippet>167</a> <span class="kw">break</span>;
<a href=#168 id=168 data-nosnippet>168</a> }
<a href=#169 id=169 data-nosnippet>169</a> }
<a href=#170 id=170 data-nosnippet>170</a>
<a href=#171 id=171 data-nosnippet>171</a> <span class="prelude-val">Ok</span>(Statement::DropTable(DropTable::new(table_names, if_exists)))
<a href=#172 id=172 data-nosnippet>172</a> }
<a href=#173 id=173 data-nosnippet>173</a>
<a href=#174 id=174 data-nosnippet>174</a> <span class="kw">fn </span>parse_drop_database(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#175 id=175 data-nosnippet>175</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#176 id=176 data-nosnippet>176</a>
<a href=#177 id=177 data-nosnippet>177</a> <span class="kw">let </span>if_exists = <span class="self">self</span>.parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::IF, Keyword::EXISTS]);
<a href=#178 id=178 data-nosnippet>178</a> <span class="kw">let </span>database_name = <span class="self">self
<a href=#179 id=179 data-nosnippet>179</a> </span>.parse_object_name()
<a href=#180 id=180 data-nosnippet>180</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#181 id=181 data-nosnippet>181</a> expected: <span class="string">"a database name"</span>,
<a href=#182 id=182 data-nosnippet>182</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#183 id=183 data-nosnippet>183</a> })<span class="question-mark">?</span>;
<a href=#184 id=184 data-nosnippet>184</a> <span class="kw">let </span>database_name = <span class="self">Self</span>::canonicalize_object_name(database_name)<span class="question-mark">?</span>;
<a href=#185 id=185 data-nosnippet>185</a>
<a href=#186 id=186 data-nosnippet>186</a> <span class="prelude-val">Ok</span>(Statement::DropDatabase(DropDatabase::new(
<a href=#187 id=187 data-nosnippet>187</a> database_name,
<a href=#188 id=188 data-nosnippet>188</a> if_exists,
<a href=#189 id=189 data-nosnippet>189</a> )))
<a href=#190 id=190 data-nosnippet>190</a> }
<a href=#191 id=191 data-nosnippet>191</a>}
<a href=#192 id=192 data-nosnippet>192</a>
<a href=#193 id=193 data-nosnippet>193</a><span class="attr">#[cfg(test)]
<a href=#194 id=194 data-nosnippet>194</a></span><span class="kw">mod </span>tests {
<a href=#195 id=195 data-nosnippet>195</a> <span class="kw">use </span>sqlparser::ast::{Ident, ObjectName};
<a href=#196 id=196 data-nosnippet>196</a>
<a href=#197 id=197 data-nosnippet>197</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#198 id=198 data-nosnippet>198</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#199 id=199 data-nosnippet>199</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#200 id=200 data-nosnippet>200</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#201 id=201 data-nosnippet>201</a> </span><span class="kw">use </span><span class="kw">crate</span>::statements::drop::UndropTable;
<a href=#202 id=202 data-nosnippet>202</a>
<a href=#203 id=203 data-nosnippet>203</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#204 id=204 data-nosnippet>204</a> #[test]
<a href=#205 id=205 data-nosnippet>205</a> </span><span class="kw">fn </span>test_undrop_table() {
<a href=#206 id=206 data-nosnippet>206</a> <span class="kw">let </span>cases = [
<a href=#207 id=207 data-nosnippet>207</a> (<span class="string">"UNDROP TABLE foo"</span>, <span class="string">"foo"</span>),
<a href=#208 id=208 data-nosnippet>208</a> (<span class="string">"undrop table my_schema.FOO"</span>, <span class="string">"my_schema.foo"</span>),
<a href=#209 id=209 data-nosnippet>209</a> (
<a href=#210 id=210 data-nosnippet>210</a> <span class="string">"UnDrOp TaBlE my_catalog.my_schema.foo"</span>,
<a href=#211 id=211 data-nosnippet>211</a> <span class="string">"my_catalog.my_schema.foo"</span>,
<a href=#212 id=212 data-nosnippet>212</a> ),
<a href=#213 id=213 data-nosnippet>213</a> (
<a href=#214 id=214 data-nosnippet>214</a> <span class="string">"UNDROP TABLE `My Catalog`.`My Schema`.`My Table`"</span>,
<a href=#215 id=215 data-nosnippet>215</a> <span class="string">"`My Catalog`.`My Schema`.`My Table`"</span>,
<a href=#216 id=216 data-nosnippet>216</a> ),
<a href=#217 id=217 data-nosnippet>217</a> ];
<a href=#218 id=218 data-nosnippet>218</a>
<a href=#219 id=219 data-nosnippet>219</a> <span class="kw">for </span>(sql, expected_name) <span class="kw">in </span>cases {
<a href=#220 id=220 data-nosnippet>220</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = ParserContext::create_with_dialect(
<a href=#221 id=221 data-nosnippet>221</a> sql,
<a href=#222 id=222 data-nosnippet>222</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#223 id=223 data-nosnippet>223</a> ParseOptions::default(),
<a href=#224 id=224 data-nosnippet>224</a> )
<a href=#225 id=225 data-nosnippet>225</a> .unwrap();
<a href=#226 id=226 data-nosnippet>226</a> <span class="kw">let </span>stmt = stmts.pop().unwrap();
<a href=#227 id=227 data-nosnippet>227</a> <span class="macro">assert_eq!</span>(
<a href=#228 id=228 data-nosnippet>228</a> stmt,
<a href=#229 id=229 data-nosnippet>229</a> Statement::UndropTable(UndropTable::new(
<a href=#230 id=230 data-nosnippet>230</a> ParserContext::parse_table_name(expected_name, <span class="kw-2">&amp;</span>GreptimeDbDialect {}).unwrap()
<a href=#231 id=231 data-nosnippet>231</a> ))
<a href=#232 id=232 data-nosnippet>232</a> );
<a href=#233 id=233 data-nosnippet>233</a> <span class="macro">assert_eq!</span>(<span class="macro">format!</span>(<span class="string">"UNDROP TABLE {expected_name}"</span>), stmt.to_string());
<a href=#234 id=234 data-nosnippet>234</a> <span class="macro">assert!</span>(!stmt.is_readonly());
<a href=#235 id=235 data-nosnippet>235</a> }
<a href=#236 id=236 data-nosnippet>236</a> }
<a href=#237 id=237 data-nosnippet>237</a>
<a href=#238 id=238 data-nosnippet>238</a> <span class="attr">#[test]
<a href=#239 id=239 data-nosnippet>239</a> </span><span class="kw">fn </span>test_undrop_table_rejects_unsupported_syntax() {
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">for </span>sql <span class="kw">in </span>[
<a href=#241 id=241 data-nosnippet>241</a> <span class="string">"UNDROP"</span>,
<a href=#242 id=242 data-nosnippet>242</a> <span class="string">"UNDROP foo"</span>,
<a href=#243 id=243 data-nosnippet>243</a> <span class="string">"UNDROP TABLE"</span>,
<a href=#244 id=244 data-nosnippet>244</a> <span class="string">"UNDROP TABLE IF EXISTS foo"</span>,
<a href=#245 id=245 data-nosnippet>245</a> <span class="string">"UNDROP TABLE foo, bar"</span>,
<a href=#246 id=246 data-nosnippet>246</a> <span class="string">"UNDROP TABLE foo bar"</span>,
<a href=#247 id=247 data-nosnippet>247</a> <span class="string">"UNDROP TABLE foo RENAME TO bar"</span>,
<a href=#248 id=248 data-nosnippet>248</a> <span class="string">"UNDROP TABLE foo AT '2026-01-01'"</span>,
<a href=#249 id=249 data-nosnippet>249</a> ] {
<a href=#250 id=250 data-nosnippet>250</a> <span class="macro">assert!</span>(
<a href=#251 id=251 data-nosnippet>251</a> ParserContext::create_with_dialect(
<a href=#252 id=252 data-nosnippet>252</a> sql,
<a href=#253 id=253 data-nosnippet>253</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#254 id=254 data-nosnippet>254</a> ParseOptions::default(),
<a href=#255 id=255 data-nosnippet>255</a> )
<a href=#256 id=256 data-nosnippet>256</a> .is_err(),
<a href=#257 id=257 data-nosnippet>257</a> <span class="string">"unexpectedly parsed: {sql}"
<a href=#258 id=258 data-nosnippet>258</a> </span>);
<a href=#259 id=259 data-nosnippet>259</a> }
<a href=#260 id=260 data-nosnippet>260</a> }
<a href=#261 id=261 data-nosnippet>261</a>
<a href=#262 id=262 data-nosnippet>262</a> <span class="attr">#[test]
<a href=#263 id=263 data-nosnippet>263</a> </span><span class="kw">pub fn </span>test_drop_table() {
<a href=#264 id=264 data-nosnippet>264</a> <span class="kw">let </span>sql = <span class="string">"DROP TABLE foo"</span>;
<a href=#265 id=265 data-nosnippet>265</a> <span class="kw">let </span>result =
<a href=#266 id=266 data-nosnippet>266</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#267 id=267 data-nosnippet>267</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#268 id=268 data-nosnippet>268</a> <span class="macro">assert_eq!</span>(
<a href=#269 id=269 data-nosnippet>269</a> stmts.pop().unwrap(),
<a href=#270 id=270 data-nosnippet>270</a> Statement::DropTable(DropTable::new(
<a href=#271 id=271 data-nosnippet>271</a> <span class="macro">vec!</span>[ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)])],
<a href=#272 id=272 data-nosnippet>272</a> <span class="bool-val">false
<a href=#273 id=273 data-nosnippet>273</a> </span>))
<a href=#274 id=274 data-nosnippet>274</a> );
<a href=#275 id=275 data-nosnippet>275</a>
<a href=#276 id=276 data-nosnippet>276</a> <span class="kw">let </span>sql = <span class="string">"DROP TABLE IF EXISTS foo"</span>;
<a href=#277 id=277 data-nosnippet>277</a> <span class="kw">let </span>result =
<a href=#278 id=278 data-nosnippet>278</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#279 id=279 data-nosnippet>279</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#280 id=280 data-nosnippet>280</a> <span class="macro">assert_eq!</span>(
<a href=#281 id=281 data-nosnippet>281</a> stmts.pop().unwrap(),
<a href=#282 id=282 data-nosnippet>282</a> Statement::DropTable(DropTable::new(
<a href=#283 id=283 data-nosnippet>283</a> <span class="macro">vec!</span>[ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)])],
<a href=#284 id=284 data-nosnippet>284</a> <span class="bool-val">true
<a href=#285 id=285 data-nosnippet>285</a> </span>))
<a href=#286 id=286 data-nosnippet>286</a> );
<a href=#287 id=287 data-nosnippet>287</a>
<a href=#288 id=288 data-nosnippet>288</a> <span class="kw">let </span>sql = <span class="string">"DROP TABLE my_schema.foo"</span>;
<a href=#289 id=289 data-nosnippet>289</a> <span class="kw">let </span>result =
<a href=#290 id=290 data-nosnippet>290</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#291 id=291 data-nosnippet>291</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#292 id=292 data-nosnippet>292</a> <span class="macro">assert_eq!</span>(
<a href=#293 id=293 data-nosnippet>293</a> stmts.pop().unwrap(),
<a href=#294 id=294 data-nosnippet>294</a> Statement::DropTable(DropTable::new(
<a href=#295 id=295 data-nosnippet>295</a> <span class="macro">vec!</span>[ObjectName::from(<span class="macro">vec!</span>[
<a href=#296 id=296 data-nosnippet>296</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#297 id=297 data-nosnippet>297</a> Ident::new(<span class="string">"foo"</span>)
<a href=#298 id=298 data-nosnippet>298</a> ])],
<a href=#299 id=299 data-nosnippet>299</a> <span class="bool-val">false
<a href=#300 id=300 data-nosnippet>300</a> </span>))
<a href=#301 id=301 data-nosnippet>301</a> );
<a href=#302 id=302 data-nosnippet>302</a>
<a href=#303 id=303 data-nosnippet>303</a> <span class="kw">let </span>sql = <span class="string">"DROP TABLE my_catalog.my_schema.foo"</span>;
<a href=#304 id=304 data-nosnippet>304</a> <span class="kw">let </span>result =
<a href=#305 id=305 data-nosnippet>305</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#306 id=306 data-nosnippet>306</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#307 id=307 data-nosnippet>307</a> <span class="macro">assert_eq!</span>(
<a href=#308 id=308 data-nosnippet>308</a> stmts.pop().unwrap(),
<a href=#309 id=309 data-nosnippet>309</a> Statement::DropTable(DropTable::new(
<a href=#310 id=310 data-nosnippet>310</a> <span class="macro">vec!</span>[ObjectName::from(<span class="macro">vec!</span>[
<a href=#311 id=311 data-nosnippet>311</a> Ident::new(<span class="string">"my_catalog"</span>),
<a href=#312 id=312 data-nosnippet>312</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#313 id=313 data-nosnippet>313</a> Ident::new(<span class="string">"foo"</span>)
<a href=#314 id=314 data-nosnippet>314</a> ])],
<a href=#315 id=315 data-nosnippet>315</a> <span class="bool-val">false
<a href=#316 id=316 data-nosnippet>316</a> </span>))
<a href=#317 id=317 data-nosnippet>317</a> )
<a href=#318 id=318 data-nosnippet>318</a> }
<a href=#319 id=319 data-nosnippet>319</a>
<a href=#320 id=320 data-nosnippet>320</a> <span class="attr">#[test]
<a href=#321 id=321 data-nosnippet>321</a> </span><span class="kw">pub fn </span>test_drop_database() {
<a href=#322 id=322 data-nosnippet>322</a> <span class="kw">let </span>sql = <span class="string">"DROP DATABASE public"</span>;
<a href=#323 id=323 data-nosnippet>323</a> <span class="kw">let </span>result =
<a href=#324 id=324 data-nosnippet>324</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#325 id=325 data-nosnippet>325</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#326 id=326 data-nosnippet>326</a> <span class="macro">assert_eq!</span>(
<a href=#327 id=327 data-nosnippet>327</a> stmts.pop().unwrap(),
<a href=#328 id=328 data-nosnippet>328</a> Statement::DropDatabase(DropDatabase::new(
<a href=#329 id=329 data-nosnippet>329</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"public"</span>)]),
<a href=#330 id=330 data-nosnippet>330</a> <span class="bool-val">false
<a href=#331 id=331 data-nosnippet>331</a> </span>))
<a href=#332 id=332 data-nosnippet>332</a> );
<a href=#333 id=333 data-nosnippet>333</a>
<a href=#334 id=334 data-nosnippet>334</a> <span class="kw">let </span>sql = <span class="string">"DROP DATABASE IF EXISTS public"</span>;
<a href=#335 id=335 data-nosnippet>335</a> <span class="kw">let </span>result =
<a href=#336 id=336 data-nosnippet>336</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#337 id=337 data-nosnippet>337</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#338 id=338 data-nosnippet>338</a> <span class="macro">assert_eq!</span>(
<a href=#339 id=339 data-nosnippet>339</a> stmts.pop().unwrap(),
<a href=#340 id=340 data-nosnippet>340</a> Statement::DropDatabase(DropDatabase::new(
<a href=#341 id=341 data-nosnippet>341</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"public"</span>)]),
<a href=#342 id=342 data-nosnippet>342</a> <span class="bool-val">true
<a href=#343 id=343 data-nosnippet>343</a> </span>))
<a href=#344 id=344 data-nosnippet>344</a> );
<a href=#345 id=345 data-nosnippet>345</a>
<a href=#346 id=346 data-nosnippet>346</a> <span class="kw">let </span>sql = <span class="string">"DROP DATABASE `fOo`"</span>;
<a href=#347 id=347 data-nosnippet>347</a> <span class="kw">let </span>result =
<a href=#348 id=348 data-nosnippet>348</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#349 id=349 data-nosnippet>349</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#350 id=350 data-nosnippet>350</a> <span class="macro">assert_eq!</span>(
<a href=#351 id=351 data-nosnippet>351</a> stmts.pop().unwrap(),
<a href=#352 id=352 data-nosnippet>352</a> Statement::DropDatabase(DropDatabase::new(
<a href=#353 id=353 data-nosnippet>353</a> ObjectName::from(<span class="macro">vec!</span>[Ident::with_quote(<span class="string">'`'</span>, <span class="string">"fOo"</span>),]),
<a href=#354 id=354 data-nosnippet>354</a> <span class="bool-val">false
<a href=#355 id=355 data-nosnippet>355</a> </span>))
<a href=#356 id=356 data-nosnippet>356</a> );
<a href=#357 id=357 data-nosnippet>357</a> }
<a href=#358 id=358 data-nosnippet>358</a>
<a href=#359 id=359 data-nosnippet>359</a> <span class="attr">#[test]
<a href=#360 id=360 data-nosnippet>360</a> </span><span class="kw">pub fn </span>test_drop_flow() {
<a href=#361 id=361 data-nosnippet>361</a> <span class="kw">let </span>sql = <span class="string">"DROP FLOW foo"</span>;
<a href=#362 id=362 data-nosnippet>362</a> <span class="kw">let </span>result =
<a href=#363 id=363 data-nosnippet>363</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#364 id=364 data-nosnippet>364</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts: Vec&lt;Statement&gt; = result.unwrap();
<a href=#365 id=365 data-nosnippet>365</a> <span class="macro">assert_eq!</span>(
<a href=#366 id=366 data-nosnippet>366</a> stmts.pop().unwrap(),
<a href=#367 id=367 data-nosnippet>367</a> Statement::DropFlow(DropFlow::new(
<a href=#368 id=368 data-nosnippet>368</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)]),
<a href=#369 id=369 data-nosnippet>369</a> <span class="bool-val">false
<a href=#370 id=370 data-nosnippet>370</a> </span>))
<a href=#371 id=371 data-nosnippet>371</a> );
<a href=#372 id=372 data-nosnippet>372</a>
<a href=#373 id=373 data-nosnippet>373</a> <span class="kw">let </span>sql = <span class="string">"DROP FLOW IF EXISTS foo"</span>;
<a href=#374 id=374 data-nosnippet>374</a> <span class="kw">let </span>result =
<a href=#375 id=375 data-nosnippet>375</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#376 id=376 data-nosnippet>376</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#377 id=377 data-nosnippet>377</a> <span class="macro">assert_eq!</span>(
<a href=#378 id=378 data-nosnippet>378</a> stmts.pop().unwrap(),
<a href=#379 id=379 data-nosnippet>379</a> Statement::DropFlow(DropFlow::new(
<a href=#380 id=380 data-nosnippet>380</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)]),
<a href=#381 id=381 data-nosnippet>381</a> <span class="bool-val">true
<a href=#382 id=382 data-nosnippet>382</a> </span>))
<a href=#383 id=383 data-nosnippet>383</a> );
<a href=#384 id=384 data-nosnippet>384</a>
<a href=#385 id=385 data-nosnippet>385</a> <span class="kw">let </span>sql = <span class="string">"DROP FLOW my_schema.foo"</span>;
<a href=#386 id=386 data-nosnippet>386</a> <span class="kw">let </span>result =
<a href=#387 id=387 data-nosnippet>387</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#388 id=388 data-nosnippet>388</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#389 id=389 data-nosnippet>389</a> <span class="macro">assert_eq!</span>(
<a href=#390 id=390 data-nosnippet>390</a> stmts.pop().unwrap(),
<a href=#391 id=391 data-nosnippet>391</a> Statement::DropFlow(DropFlow::new(
<a href=#392 id=392 data-nosnippet>392</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"my_schema"</span>), Ident::new(<span class="string">"foo"</span>)]),
<a href=#393 id=393 data-nosnippet>393</a> <span class="bool-val">false
<a href=#394 id=394 data-nosnippet>394</a> </span>))
<a href=#395 id=395 data-nosnippet>395</a> );
<a href=#396 id=396 data-nosnippet>396</a>
<a href=#397 id=397 data-nosnippet>397</a> <span class="kw">let </span>sql = <span class="string">"DROP FLOW my_catalog.my_schema.foo"</span>;
<a href=#398 id=398 data-nosnippet>398</a> <span class="kw">let </span>result =
<a href=#399 id=399 data-nosnippet>399</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#400 id=400 data-nosnippet>400</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#401 id=401 data-nosnippet>401</a> <span class="macro">assert_eq!</span>(
<a href=#402 id=402 data-nosnippet>402</a> stmts.pop().unwrap(),
<a href=#403 id=403 data-nosnippet>403</a> Statement::DropFlow(DropFlow::new(
<a href=#404 id=404 data-nosnippet>404</a> ObjectName::from(<span class="macro">vec!</span>[
<a href=#405 id=405 data-nosnippet>405</a> Ident::new(<span class="string">"my_catalog"</span>),
<a href=#406 id=406 data-nosnippet>406</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#407 id=407 data-nosnippet>407</a> Ident::new(<span class="string">"foo"</span>)
<a href=#408 id=408 data-nosnippet>408</a> ]),
<a href=#409 id=409 data-nosnippet>409</a> <span class="bool-val">false
<a href=#410 id=410 data-nosnippet>410</a> </span>))
<a href=#411 id=411 data-nosnippet>411</a> )
<a href=#412 id=412 data-nosnippet>412</a> }
<a href=#413 id=413 data-nosnippet>413</a>
<a href=#414 id=414 data-nosnippet>414</a> <span class="attr">#[test]
<a href=#415 id=415 data-nosnippet>415</a> </span><span class="kw">pub fn </span>test_drop_view() {
<a href=#416 id=416 data-nosnippet>416</a> <span class="kw">let </span>sql = <span class="string">"DROP VIEW foo"</span>;
<a href=#417 id=417 data-nosnippet>417</a> <span class="kw">let </span>result =
<a href=#418 id=418 data-nosnippet>418</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#419 id=419 data-nosnippet>419</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts: Vec&lt;Statement&gt; = result.unwrap();
<a href=#420 id=420 data-nosnippet>420</a> <span class="kw">let </span>stmt = stmts.pop().unwrap();
<a href=#421 id=421 data-nosnippet>421</a> <span class="macro">assert_eq!</span>(
<a href=#422 id=422 data-nosnippet>422</a> stmt,
<a href=#423 id=423 data-nosnippet>423</a> Statement::DropView(DropView {
<a href=#424 id=424 data-nosnippet>424</a> view_name: ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)]),
<a href=#425 id=425 data-nosnippet>425</a> drop_if_exists: <span class="bool-val">false</span>,
<a href=#426 id=426 data-nosnippet>426</a> })
<a href=#427 id=427 data-nosnippet>427</a> );
<a href=#428 id=428 data-nosnippet>428</a> <span class="macro">assert_eq!</span>(sql, stmt.to_string());
<a href=#429 id=429 data-nosnippet>429</a>
<a href=#430 id=430 data-nosnippet>430</a> <span class="kw">let </span>sql = <span class="string">"DROP VIEW greptime.public.foo"</span>;
<a href=#431 id=431 data-nosnippet>431</a> <span class="kw">let </span>result =
<a href=#432 id=432 data-nosnippet>432</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#433 id=433 data-nosnippet>433</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts: Vec&lt;Statement&gt; = result.unwrap();
<a href=#434 id=434 data-nosnippet>434</a> <span class="kw">let </span>stmt = stmts.pop().unwrap();
<a href=#435 id=435 data-nosnippet>435</a> <span class="macro">assert_eq!</span>(
<a href=#436 id=436 data-nosnippet>436</a> stmt,
<a href=#437 id=437 data-nosnippet>437</a> Statement::DropView(DropView {
<a href=#438 id=438 data-nosnippet>438</a> view_name: ObjectName::from(<span class="macro">vec!</span>[
<a href=#439 id=439 data-nosnippet>439</a> Ident::new(<span class="string">"greptime"</span>),
<a href=#440 id=440 data-nosnippet>440</a> Ident::new(<span class="string">"public"</span>),
<a href=#441 id=441 data-nosnippet>441</a> Ident::new(<span class="string">"foo"</span>)
<a href=#442 id=442 data-nosnippet>442</a> ]),
<a href=#443 id=443 data-nosnippet>443</a> drop_if_exists: <span class="bool-val">false</span>,
<a href=#444 id=444 data-nosnippet>444</a> })
<a href=#445 id=445 data-nosnippet>445</a> );
<a href=#446 id=446 data-nosnippet>446</a> <span class="macro">assert_eq!</span>(sql, stmt.to_string());
<a href=#447 id=447 data-nosnippet>447</a>
<a href=#448 id=448 data-nosnippet>448</a> <span class="kw">let </span>sql = <span class="string">"DROP VIEW IF EXISTS foo"</span>;
<a href=#449 id=449 data-nosnippet>449</a> <span class="kw">let </span>result =
<a href=#450 id=450 data-nosnippet>450</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#451 id=451 data-nosnippet>451</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts: Vec&lt;Statement&gt; = result.unwrap();
<a href=#452 id=452 data-nosnippet>452</a> <span class="kw">let </span>stmt = stmts.pop().unwrap();
<a href=#453 id=453 data-nosnippet>453</a> <span class="macro">assert_eq!</span>(
<a href=#454 id=454 data-nosnippet>454</a> stmt,
<a href=#455 id=455 data-nosnippet>455</a> Statement::DropView(DropView {
<a href=#456 id=456 data-nosnippet>456</a> view_name: ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)]),
<a href=#457 id=457 data-nosnippet>457</a> drop_if_exists: <span class="bool-val">true</span>,
<a href=#458 id=458 data-nosnippet>458</a> })
<a href=#459 id=459 data-nosnippet>459</a> );
<a href=#460 id=460 data-nosnippet>460</a> <span class="macro">assert_eq!</span>(sql, stmt.to_string());
<a href=#461 id=461 data-nosnippet>461</a> }
<a href=#462 id=462 data-nosnippet>462</a>}
</code></pre></div></section></main></body></html>
+43
View File
@@ -0,0 +1,43 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/error.rs`."><title>error.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>error.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>common_macro::stack_trace_debug;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>snafu::{Location, Snafu};
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::parser::ParserError;
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="doccomment">/// TQL parser &amp; evaluation errors.
<a href=#20 id=20 data-nosnippet>20</a></span><span class="attr">#[derive(Snafu)]
<a href=#21 id=21 data-nosnippet>21</a>#[snafu(visibility(<span class="kw">pub</span>))]
<a href=#22 id=22 data-nosnippet>22</a>#[stack_trace_debug]
<a href=#23 id=23 data-nosnippet>23</a></span><span class="kw">pub enum </span>TQLError {
<a href=#24 id=24 data-nosnippet>24</a> <span class="attr">#[snafu(display(<span class="string">"Failed to parse TQL expression"</span>))]
<a href=#25 id=25 data-nosnippet>25</a> </span>Parser {
<a href=#26 id=26 data-nosnippet>26</a> <span class="attr">#[snafu(source)]
<a href=#27 id=27 data-nosnippet>27</a> </span>error: ParserError,
<a href=#28 id=28 data-nosnippet>28</a> <span class="attr">#[snafu(implicit)]
<a href=#29 id=29 data-nosnippet>29</a> </span>location: Location,
<a href=#30 id=30 data-nosnippet>30</a> },
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a> <span class="attr">#[snafu(display(<span class="string">"Failed to evaluate TQL expression: {}"</span>, msg))]
<a href=#33 id=33 data-nosnippet>33</a> </span>Evaluation { msg: String },
<a href=#34 id=34 data-nosnippet>34</a>
<a href=#35 id=35 data-nosnippet>35</a> <span class="attr">#[snafu(display(<span class="string">"Failed to convert TQL expression to logical expression"</span>))]
<a href=#36 id=36 data-nosnippet>36</a> </span>ConvertToLogicalExpression {
<a href=#37 id=37 data-nosnippet>37</a> <span class="attr">#[snafu(source)]
<a href=#38 id=38 data-nosnippet>38</a> </span>error: Box&lt;<span class="kw">crate</span>::error::Error&gt;,
<a href=#39 id=39 data-nosnippet>39</a> <span class="attr">#[snafu(implicit)]
<a href=#40 id=40 data-nosnippet>40</a> </span>location: Location,
<a href=#41 id=41 data-nosnippet>41</a> },
<a href=#42 id=42 data-nosnippet>42</a>}
</code></pre></div></section></main></body></html>
+42
View File
@@ -0,0 +1,42 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/execute_parser.rs`."><title>execute_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>execute_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::Expr;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::parser::Parser;
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="prelude-ty">Result</span>, SyntaxSnafu};
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#24 id=24 data-nosnippet>24</a> <span class="doccomment">/// Parses MySQL style 'EXECUTE stmt_name USING param_list' into a stmt_name string and a list of parameters.
<a href=#25 id=25 data-nosnippet>25</a> /// Only use for MySQL. for PostgreSQL, use `sqlparser::parser::Parser::parse_execute` instead.
<a href=#26 id=26 data-nosnippet>26</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_mysql_execute(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;(String, Vec&lt;Expr&gt;)&gt; {
<a href=#27 id=27 data-nosnippet>27</a> <span class="self">self</span>.parser
<a href=#28 id=28 data-nosnippet>28</a> .expect_keyword(Keyword::EXECUTE)
<a href=#29 id=29 data-nosnippet>29</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">let </span>stmt_name = <span class="self">self</span>.parser.parse_identifier().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::USING) {
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">let </span>param_list = <span class="self">self
<a href=#33 id=33 data-nosnippet>33</a> </span>.parser
<a href=#34 id=34 data-nosnippet>34</a> .parse_comma_separated(Parser::parse_expr)
<a href=#35 id=35 data-nosnippet>35</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#36 id=36 data-nosnippet>36</a> <span class="prelude-val">Ok</span>((stmt_name.value, param_list))
<a href=#37 id=37 data-nosnippet>37</a> } <span class="kw">else </span>{
<a href=#38 id=38 data-nosnippet>38</a> <span class="prelude-val">Ok</span>((stmt_name.value, <span class="macro">vec!</span>[]))
<a href=#39 id=39 data-nosnippet>39</a> }
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a>}
</code></pre></div></section></main></body></html>
+140
View File
@@ -0,0 +1,140 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/explain_parser.rs`."><title>explain_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>explain_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::statements::explain::ExplainStatement;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// EXPLAIN statement parser implementation
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#25 id=25 data-nosnippet>25</a> <span class="doccomment">/// explain that support use our own parser to parse the inner statement
<a href=#26 id=26 data-nosnippet>26</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_explain(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let </span>analyze = <span class="self">self</span>.parser.parse_keyword(Keyword::ANALYZE);
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">let </span>verbose = <span class="self">self</span>.parser.parse_keyword(Keyword::VERBOSE);
<a href=#29 id=29 data-nosnippet>29</a> <span class="kw">let </span>format =
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">if </span><span class="self">self</span>.parser.parse_keyword(Keyword::FORMAT) {
<a href=#31 id=31 data-nosnippet>31</a> <span class="prelude-val">Some</span>(<span class="self">self</span>.parser.parse_analyze_format().with_context(|<span class="kw">_</span>| {
<a href=#32 id=32 data-nosnippet>32</a> error::UnexpectedSnafu {
<a href=#33 id=33 data-nosnippet>33</a> expected: <span class="string">"analyze format"</span>,
<a href=#34 id=34 data-nosnippet>34</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#35 id=35 data-nosnippet>35</a> }
<a href=#36 id=36 data-nosnippet>36</a> })<span class="question-mark">?</span>)
<a href=#37 id=37 data-nosnippet>37</a> } <span class="kw">else </span>{
<a href=#38 id=38 data-nosnippet>38</a> <span class="prelude-val">None
<a href=#39 id=39 data-nosnippet>39</a> </span>};
<a href=#40 id=40 data-nosnippet>40</a>
<a href=#41 id=41 data-nosnippet>41</a> <span class="kw">let </span>statement = <span class="self">self</span>.parse_statement()<span class="question-mark">?</span>;
<a href=#42 id=42 data-nosnippet>42</a>
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw">let </span>explain = ExplainStatement {
<a href=#44 id=44 data-nosnippet>44</a> analyze,
<a href=#45 id=45 data-nosnippet>45</a> verbose,
<a href=#46 id=46 data-nosnippet>46</a> format,
<a href=#47 id=47 data-nosnippet>47</a> statement: Box::new(statement),
<a href=#48 id=48 data-nosnippet>48</a> };
<a href=#49 id=49 data-nosnippet>49</a> <span class="prelude-val">Ok</span>(Statement::Explain(Box::new(explain)))
<a href=#50 id=50 data-nosnippet>50</a> }
<a href=#51 id=51 data-nosnippet>51</a>}
<a href=#52 id=52 data-nosnippet>52</a>
<a href=#53 id=53 data-nosnippet>53</a><span class="attr">#[cfg(test)]
<a href=#54 id=54 data-nosnippet>54</a></span><span class="kw">mod </span>tests {
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">use </span>sqlparser::ast::helpers::attached_token::AttachedToken;
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">use </span>sqlparser::ast::{GroupByExpr, Query <span class="kw">as </span>SpQuery, SelectFlavor, WildcardAdditionalOptions};
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#61 id=61 data-nosnippet>61</a>
<a href=#62 id=62 data-nosnippet>62</a> <span class="attr">#[test]
<a href=#63 id=63 data-nosnippet>63</a> </span><span class="kw">pub fn </span>test_explain() {
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">let </span>sql = <span class="string">"EXPLAIN select * from foo"</span>;
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">let </span>result =
<a href=#66 id=66 data-nosnippet>66</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">let </span>stmts = result.unwrap();
<a href=#68 id=68 data-nosnippet>68</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#69 id=69 data-nosnippet>69</a>
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">let </span>select = sqlparser::ast::Select {
<a href=#71 id=71 data-nosnippet>71</a> distinct: <span class="prelude-val">None</span>,
<a href=#72 id=72 data-nosnippet>72</a> select_modifiers: <span class="prelude-val">None</span>,
<a href=#73 id=73 data-nosnippet>73</a> top: <span class="prelude-val">None</span>,
<a href=#74 id=74 data-nosnippet>74</a> projection: <span class="macro">vec!</span>[sqlparser::ast::SelectItem::Wildcard(
<a href=#75 id=75 data-nosnippet>75</a> WildcardAdditionalOptions::default(),
<a href=#76 id=76 data-nosnippet>76</a> )],
<a href=#77 id=77 data-nosnippet>77</a> exclude: <span class="prelude-val">None</span>,
<a href=#78 id=78 data-nosnippet>78</a> into: <span class="prelude-val">None</span>,
<a href=#79 id=79 data-nosnippet>79</a> from: <span class="macro">vec!</span>[sqlparser::ast::TableWithJoins {
<a href=#80 id=80 data-nosnippet>80</a> relation: sqlparser::ast::TableFactor::Table {
<a href=#81 id=81 data-nosnippet>81</a> name: sqlparser::ast::ObjectName::from(<span class="macro">vec!</span>[sqlparser::ast::Ident::new(<span class="string">"foo"</span>)]),
<a href=#82 id=82 data-nosnippet>82</a> alias: <span class="prelude-val">None</span>,
<a href=#83 id=83 data-nosnippet>83</a> args: <span class="prelude-val">None</span>,
<a href=#84 id=84 data-nosnippet>84</a> with_hints: <span class="macro">vec!</span>[],
<a href=#85 id=85 data-nosnippet>85</a> partitions: <span class="macro">vec!</span>[],
<a href=#86 id=86 data-nosnippet>86</a> version: <span class="prelude-val">None</span>,
<a href=#87 id=87 data-nosnippet>87</a> with_ordinality: <span class="bool-val">false</span>,
<a href=#88 id=88 data-nosnippet>88</a> json_path: <span class="prelude-val">None</span>,
<a href=#89 id=89 data-nosnippet>89</a> sample: <span class="prelude-val">None</span>,
<a href=#90 id=90 data-nosnippet>90</a> index_hints: <span class="macro">vec!</span>[],
<a href=#91 id=91 data-nosnippet>91</a> },
<a href=#92 id=92 data-nosnippet>92</a> joins: <span class="macro">vec!</span>[],
<a href=#93 id=93 data-nosnippet>93</a> }],
<a href=#94 id=94 data-nosnippet>94</a> lateral_views: <span class="macro">vec!</span>[],
<a href=#95 id=95 data-nosnippet>95</a> selection: <span class="prelude-val">None</span>,
<a href=#96 id=96 data-nosnippet>96</a> group_by: GroupByExpr::Expressions(<span class="macro">vec!</span>[], <span class="macro">vec!</span>[]),
<a href=#97 id=97 data-nosnippet>97</a> cluster_by: <span class="macro">vec!</span>[],
<a href=#98 id=98 data-nosnippet>98</a> distribute_by: <span class="macro">vec!</span>[],
<a href=#99 id=99 data-nosnippet>99</a> sort_by: <span class="macro">vec!</span>[],
<a href=#100 id=100 data-nosnippet>100</a> having: <span class="prelude-val">None</span>,
<a href=#101 id=101 data-nosnippet>101</a> qualify: <span class="prelude-val">None</span>,
<a href=#102 id=102 data-nosnippet>102</a> named_window: <span class="macro">vec!</span>[],
<a href=#103 id=103 data-nosnippet>103</a> value_table_mode: <span class="prelude-val">None</span>,
<a href=#104 id=104 data-nosnippet>104</a> top_before_distinct: <span class="bool-val">false</span>,
<a href=#105 id=105 data-nosnippet>105</a> prewhere: <span class="prelude-val">None</span>,
<a href=#106 id=106 data-nosnippet>106</a> window_before_qualify: <span class="bool-val">false</span>,
<a href=#107 id=107 data-nosnippet>107</a> connect_by: <span class="macro">vec!</span>[],
<a href=#108 id=108 data-nosnippet>108</a> select_token: AttachedToken::empty(),
<a href=#109 id=109 data-nosnippet>109</a> flavor: SelectFlavor::Standard,
<a href=#110 id=110 data-nosnippet>110</a> optimizer_hints: <span class="macro">vec!</span>[],
<a href=#111 id=111 data-nosnippet>111</a> };
<a href=#112 id=112 data-nosnippet>112</a>
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">let </span>sp_query = Box::new(
<a href=#114 id=114 data-nosnippet>114</a> SpQuery {
<a href=#115 id=115 data-nosnippet>115</a> with: <span class="prelude-val">None</span>,
<a href=#116 id=116 data-nosnippet>116</a> body: Box::new(sqlparser::ast::SetExpr::Select(Box::new(select))),
<a href=#117 id=117 data-nosnippet>117</a> order_by: <span class="prelude-val">None</span>,
<a href=#118 id=118 data-nosnippet>118</a> limit_clause: <span class="prelude-val">None</span>,
<a href=#119 id=119 data-nosnippet>119</a> pipe_operators: <span class="macro">vec!</span>[],
<a href=#120 id=120 data-nosnippet>120</a> fetch: <span class="prelude-val">None</span>,
<a href=#121 id=121 data-nosnippet>121</a> locks: <span class="macro">vec!</span>[],
<a href=#122 id=122 data-nosnippet>122</a> for_clause: <span class="prelude-val">None</span>,
<a href=#123 id=123 data-nosnippet>123</a> settings: <span class="prelude-val">None</span>,
<a href=#124 id=124 data-nosnippet>124</a> format_clause: <span class="prelude-val">None</span>,
<a href=#125 id=125 data-nosnippet>125</a> }
<a href=#126 id=126 data-nosnippet>126</a> .try_into()
<a href=#127 id=127 data-nosnippet>127</a> .unwrap(),
<a href=#128 id=128 data-nosnippet>128</a> );
<a href=#129 id=129 data-nosnippet>129</a>
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">let </span>explain = ExplainStatement {
<a href=#131 id=131 data-nosnippet>131</a> analyze: <span class="bool-val">false</span>,
<a href=#132 id=132 data-nosnippet>132</a> verbose: <span class="bool-val">false</span>,
<a href=#133 id=133 data-nosnippet>133</a> format: <span class="prelude-val">None</span>,
<a href=#134 id=134 data-nosnippet>134</a> statement: Box::new(Statement::Query(sp_query)),
<a href=#135 id=135 data-nosnippet>135</a> };
<a href=#136 id=136 data-nosnippet>136</a>
<a href=#137 id=137 data-nosnippet>137</a> <span class="macro">assert_eq!</span>(stmts[<span class="number">0</span>], Statement::Explain(Box::new(explain)))
<a href=#138 id=138 data-nosnippet>138</a> }
<a href=#139 id=139 data-nosnippet>139</a>}
</code></pre></div></section></main></body></html>
+96
View File
@@ -0,0 +1,96 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/insert_parser.rs`."><title>insert_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>insert_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::Statement <span class="kw">as </span>SpStatement;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::statements::insert::Insert;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// INSERT/REPLACE statement parser implementation
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#25 id=25 data-nosnippet>25</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_insert(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">let </span>token = <span class="self">self</span>.parser.next_token();
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let </span>spstatement = <span class="self">self
<a href=#28 id=28 data-nosnippet>28</a> </span>.parser
<a href=#29 id=29 data-nosnippet>29</a> .parse_insert(token)
<a href=#30 id=30 data-nosnippet>30</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">match </span>spstatement {
<a href=#33 id=33 data-nosnippet>33</a> insert_stmt @ SpStatement::Insert { .. } =&gt; {
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">let </span>insert = Insert::try_from(insert_stmt)
<a href=#35 id=35 data-nosnippet>35</a> .map_err(|e| error::InvalidSqlSnafu { msg: e.to_string() }.build())<span class="question-mark">?</span>;
<a href=#36 id=36 data-nosnippet>36</a> <span class="prelude-val">Ok</span>(Statement::Insert(Box::new(insert)))
<a href=#37 id=37 data-nosnippet>37</a> }
<a href=#38 id=38 data-nosnippet>38</a> unexp =&gt; error::UnsupportedSnafu {
<a href=#39 id=39 data-nosnippet>39</a> keyword: unexp.to_string(),
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a> .fail(),
<a href=#42 id=42 data-nosnippet>42</a> }
<a href=#43 id=43 data-nosnippet>43</a> }
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_replace(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">let </span>token = <span class="self">self</span>.parser.next_token();
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">let </span>spstatement = <span class="self">self
<a href=#48 id=48 data-nosnippet>48</a> </span>.parser
<a href=#49 id=49 data-nosnippet>49</a> .parse_insert(token)
<a href=#50 id=50 data-nosnippet>50</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#51 id=51 data-nosnippet>51</a>
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">match </span>spstatement {
<a href=#53 id=53 data-nosnippet>53</a> SpStatement::Insert(<span class="kw-2">mut </span>insert_stmt) =&gt; {
<a href=#54 id=54 data-nosnippet>54</a> insert_stmt.replace_into = <span class="bool-val">true</span>;
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">let </span>insert = Insert::try_from(SpStatement::Insert(insert_stmt))
<a href=#56 id=56 data-nosnippet>56</a> .map_err(|e| error::InvalidSqlSnafu { msg: e.to_string() }.build())<span class="question-mark">?</span>;
<a href=#57 id=57 data-nosnippet>57</a> <span class="prelude-val">Ok</span>(Statement::Insert(Box::new(insert)))
<a href=#58 id=58 data-nosnippet>58</a> }
<a href=#59 id=59 data-nosnippet>59</a> unexp =&gt; error::UnsupportedSnafu {
<a href=#60 id=60 data-nosnippet>60</a> keyword: unexp.to_string(),
<a href=#61 id=61 data-nosnippet>61</a> }
<a href=#62 id=62 data-nosnippet>62</a> .fail(),
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a> }
<a href=#65 id=65 data-nosnippet>65</a>}
<a href=#66 id=66 data-nosnippet>66</a>
<a href=#67 id=67 data-nosnippet>67</a><span class="attr">#[cfg(test)]
<a href=#68 id=68 data-nosnippet>68</a></span><span class="kw">mod </span>tests {
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">use </span>std::assert_matches;
<a href=#70 id=70 data-nosnippet>70</a>
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#74 id=74 data-nosnippet>74</a>
<a href=#75 id=75 data-nosnippet>75</a> <span class="attr">#[test]
<a href=#76 id=76 data-nosnippet>76</a> </span><span class="kw">pub fn </span>test_parse_insert() {
<a href=#77 id=77 data-nosnippet>77</a> <span class="kw">let </span>sql = <span class="string">r"INSERT INTO table_1 VALUES (
<a href=#78 id=78 data-nosnippet>78</a> 'test1',1,'true',
<a href=#79 id=79 data-nosnippet>79</a> 'test2',2,'false')
<a href=#80 id=80 data-nosnippet>80</a> "</span>;
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">let </span>result =
<a href=#82 id=82 data-nosnippet>82</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#83 id=83 data-nosnippet>83</a> .unwrap();
<a href=#84 id=84 data-nosnippet>84</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, result.len());
<a href=#85 id=85 data-nosnippet>85</a> <span class="macro">assert_matches!</span>(result[<span class="number">0</span>], Statement::Insert { .. })
<a href=#86 id=86 data-nosnippet>86</a> }
<a href=#87 id=87 data-nosnippet>87</a>
<a href=#88 id=88 data-nosnippet>88</a> <span class="attr">#[test]
<a href=#89 id=89 data-nosnippet>89</a> </span><span class="kw">pub fn </span>test_parse_invalid_insert() {
<a href=#90 id=90 data-nosnippet>90</a> <span class="kw">let </span>sql = <span class="string">r"INSERT INTO table_1 VALUES ("</span>; <span class="comment">// intentionally a bad sql
<a href=#91 id=91 data-nosnippet>91</a> </span><span class="kw">let </span>result =
<a href=#92 id=92 data-nosnippet>92</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#93 id=93 data-nosnippet>93</a> <span class="macro">assert!</span>(result.is_err(), <span class="string">"result is: {result:?}"</span>);
<a href=#94 id=94 data-nosnippet>94</a> }
<a href=#95 id=95 data-nosnippet>95</a>}
</code></pre></div></section></main></body></html>
+47
View File
@@ -0,0 +1,47 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/prepare_parser.rs`."><title>prepare_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>prepare_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="prelude-ty">Result</span>, SyntaxSnafu};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#23 id=23 data-nosnippet>23</a> <span class="doccomment">/// Parses MySQL style 'PREPARE stmt_name FROM stmt' into a (stmt_name, stmt) tuple.
<a href=#24 id=24 data-nosnippet>24</a> /// Only use for MySQL. for PostgreSQL, use `sqlparser::parser::Parser::parse_prepare` instead.
<a href=#25 id=25 data-nosnippet>25</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_mysql_prepare(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;(String, String)&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="self">self</span>.parser
<a href=#27 id=27 data-nosnippet>27</a> .expect_keyword(Keyword::PREPARE)
<a href=#28 id=28 data-nosnippet>28</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#29 id=29 data-nosnippet>29</a> <span class="kw">let </span>stmt_name = <span class="self">self</span>.parser.parse_identifier().context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#30 id=30 data-nosnippet>30</a> <span class="self">self</span>.parser
<a href=#31 id=31 data-nosnippet>31</a> .expect_keyword(Keyword::FROM)
<a href=#32 id=32 data-nosnippet>32</a> .context(SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">let </span>next_token = <span class="self">self</span>.parser.peek_token();
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">let </span>stmt = <span class="kw">match </span>next_token.token {
<a href=#35 id=35 data-nosnippet>35</a> Token::SingleQuotedString(s) | Token::DoubleQuotedString(s) =&gt; {
<a href=#36 id=36 data-nosnippet>36</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#37 id=37 data-nosnippet>37</a> s
<a href=#38 id=38 data-nosnippet>38</a> }
<a href=#39 id=39 data-nosnippet>39</a> <span class="kw">_ </span>=&gt; <span class="self">self
<a href=#40 id=40 data-nosnippet>40</a> </span>.parser
<a href=#41 id=41 data-nosnippet>41</a> .expected(<span class="string">"string literal"</span>, next_token)
<a href=#42 id=42 data-nosnippet>42</a> .context(SyntaxSnafu)<span class="question-mark">?</span>,
<a href=#43 id=43 data-nosnippet>43</a> };
<a href=#44 id=44 data-nosnippet>44</a> <span class="prelude-val">Ok</span>((stmt_name.value, stmt))
<a href=#45 id=45 data-nosnippet>45</a> }
<a href=#46 id=46 data-nosnippet>46</a>}
</code></pre></div></section></main></body></html>
+64
View File
@@ -0,0 +1,64 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/query_parser.rs`."><title>query_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>query_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::prelude::<span class="kw-2">*</span>;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::statements::query::Query;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#23 id=23 data-nosnippet>23</a> <span class="doccomment">/// Parses select and it's variants.
<a href=#24 id=24 data-nosnippet>24</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_query(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#25 id=25 data-nosnippet>25</a> <span class="kw">let </span>spquery = <span class="self">self</span>.parser.parse_query().context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#26 id=26 data-nosnippet>26</a>
<a href=#27 id=27 data-nosnippet>27</a> <span class="prelude-val">Ok</span>(Statement::Query(Box::new(Query::try_from(<span class="kw-2">*</span>spquery)<span class="question-mark">?</span>)))
<a href=#28 id=28 data-nosnippet>28</a> }
<a href=#29 id=29 data-nosnippet>29</a>}
<a href=#30 id=30 data-nosnippet>30</a>
<a href=#31 id=31 data-nosnippet>31</a><span class="attr">#[cfg(test)]
<a href=#32 id=32 data-nosnippet>32</a></span><span class="kw">mod </span>tests {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">use </span>common_error::ext::ErrorExt;
<a href=#34 id=34 data-nosnippet>34</a>
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#36 id=36 data-nosnippet>36</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a> <span class="attr">#[test]
<a href=#39 id=39 data-nosnippet>39</a> </span><span class="kw">pub fn </span>test_parse_query() {
<a href=#40 id=40 data-nosnippet>40</a> <span class="kw">let </span>sql = <span class="string">"SELECT a, b, 123, myfunc(b) \
<a href=#41 id=41 data-nosnippet>41</a> FROM table_1 \
<a href=#42 id=42 data-nosnippet>42</a> WHERE a &gt; b AND b &lt; 100 \
<a href=#43 id=43 data-nosnippet>43</a> ORDER BY a DESC, b"</span>;
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a> <span class="kw">let _ </span>=
<a href=#46 id=46 data-nosnippet>46</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#47 id=47 data-nosnippet>47</a> .unwrap();
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a>
<a href=#50 id=50 data-nosnippet>50</a> <span class="attr">#[test]
<a href=#51 id=51 data-nosnippet>51</a> </span><span class="kw">pub fn </span>test_parse_invalid_query() {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">let </span>sql = <span class="string">"SELECT * FROM table_1 WHERE"</span>;
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">let </span>result =
<a href=#54 id=54 data-nosnippet>54</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#55 id=55 data-nosnippet>55</a> <span class="macro">assert!</span>(result.is_err());
<a href=#56 id=56 data-nosnippet>56</a> <span class="macro">assert!</span>(
<a href=#57 id=57 data-nosnippet>57</a> result
<a href=#58 id=58 data-nosnippet>58</a> .unwrap_err()
<a href=#59 id=59 data-nosnippet>59</a> .output_msg()
<a href=#60 id=60 data-nosnippet>60</a> .contains(<span class="string">"Expected: an expression"</span>)
<a href=#61 id=61 data-nosnippet>61</a> );
<a href=#62 id=62 data-nosnippet>62</a> }
<a href=#63 id=63 data-nosnippet>63</a>}
</code></pre></div></section></main></body></html>
+157
View File
@@ -0,0 +1,157 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/set_var_parser.rs`."><title>set_var_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>set_var_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ResultExt;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::{Set, Statement <span class="kw">as </span>SpStatement};
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::ast::{Ident, ObjectName};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::set_variables::SetVariables;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="doccomment">/// SET variables statement parser implementation
<a href=#25 id=25 data-nosnippet>25</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_set_variables(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let </span>spstatement = <span class="self">self</span>.parser.parse_statement().context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">match </span>spstatement {
<a href=#29 id=29 data-nosnippet>29</a> SpStatement::Set(set) =&gt; <span class="kw">match </span>set {
<a href=#30 id=30 data-nosnippet>30</a> Set::SingleAssignment {
<a href=#31 id=31 data-nosnippet>31</a> scope: <span class="kw">_</span>,
<a href=#32 id=32 data-nosnippet>32</a> hivevar,
<a href=#33 id=33 data-nosnippet>33</a> variable,
<a href=#34 id=34 data-nosnippet>34</a> values,
<a href=#35 id=35 data-nosnippet>35</a> } <span class="kw">if </span>!hivevar =&gt; <span class="prelude-val">Ok</span>(Statement::SetVariables(SetVariables {
<a href=#36 id=36 data-nosnippet>36</a> variable,
<a href=#37 id=37 data-nosnippet>37</a> value: values,
<a href=#38 id=38 data-nosnippet>38</a> })),
<a href=#39 id=39 data-nosnippet>39</a>
<a href=#40 id=40 data-nosnippet>40</a> Set::SetTimeZone { local: <span class="kw">_</span>, value } =&gt; <span class="prelude-val">Ok</span>(Statement::SetVariables(SetVariables {
<a href=#41 id=41 data-nosnippet>41</a> variable: ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"TIMEZONE"</span>)]),
<a href=#42 id=42 data-nosnippet>42</a> value: <span class="macro">vec!</span>[value],
<a href=#43 id=43 data-nosnippet>43</a> })),
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a> set =&gt; error::UnsupportedSnafu {
<a href=#46 id=46 data-nosnippet>46</a> keyword: set.to_string(),
<a href=#47 id=47 data-nosnippet>47</a> }
<a href=#48 id=48 data-nosnippet>48</a> .fail(),
<a href=#49 id=49 data-nosnippet>49</a> },
<a href=#50 id=50 data-nosnippet>50</a> unexp =&gt; error::UnsupportedSnafu {
<a href=#51 id=51 data-nosnippet>51</a> keyword: unexp.to_string(),
<a href=#52 id=52 data-nosnippet>52</a> }
<a href=#53 id=53 data-nosnippet>53</a> .fail(),
<a href=#54 id=54 data-nosnippet>54</a> }
<a href=#55 id=55 data-nosnippet>55</a> }
<a href=#56 id=56 data-nosnippet>56</a>}
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a><span class="attr">#[cfg(test)]
<a href=#59 id=59 data-nosnippet>59</a></span><span class="kw">mod </span>tests {
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">use </span>sqlparser::ast::{Expr, Ident, ObjectName, Value};
<a href=#61 id=61 data-nosnippet>61</a>
<a href=#62 id=62 data-nosnippet>62</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#63 id=63 data-nosnippet>63</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#65 id=65 data-nosnippet>65</a>
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">fn </span>assert_mysql_parse_result(sql: <span class="kw-2">&amp;</span>str, indent_str: <span class="kw-2">&amp;</span>str, expr: Expr) {
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">let </span>result =
<a href=#68 id=68 data-nosnippet>68</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#70 id=70 data-nosnippet>70</a> <span class="macro">assert_eq!</span>(
<a href=#71 id=71 data-nosnippet>71</a> stmts.pop().unwrap(),
<a href=#72 id=72 data-nosnippet>72</a> Statement::SetVariables(SetVariables {
<a href=#73 id=73 data-nosnippet>73</a> variable: ObjectName::from(<span class="macro">vec!</span>[Ident::new(indent_str)]),
<a href=#74 id=74 data-nosnippet>74</a> value: <span class="macro">vec!</span>[expr]
<a href=#75 id=75 data-nosnippet>75</a> })
<a href=#76 id=76 data-nosnippet>76</a> );
<a href=#77 id=77 data-nosnippet>77</a> }
<a href=#78 id=78 data-nosnippet>78</a>
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw">fn </span>assert_pg_parse_result(sql: <span class="kw-2">&amp;</span>str, indent: <span class="kw-2">&amp;</span>str, expr: Expr) {
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">let </span>result =
<a href=#81 id=81 data-nosnippet>81</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts = result.unwrap();
<a href=#83 id=83 data-nosnippet>83</a> <span class="macro">assert_eq!</span>(
<a href=#84 id=84 data-nosnippet>84</a> stmts.pop().unwrap(),
<a href=#85 id=85 data-nosnippet>85</a> Statement::SetVariables(SetVariables {
<a href=#86 id=86 data-nosnippet>86</a> variable: ObjectName::from(<span class="macro">vec!</span>[Ident::new(indent)]),
<a href=#87 id=87 data-nosnippet>87</a> value: <span class="macro">vec!</span>[expr],
<a href=#88 id=88 data-nosnippet>88</a> })
<a href=#89 id=89 data-nosnippet>89</a> );
<a href=#90 id=90 data-nosnippet>90</a> }
<a href=#91 id=91 data-nosnippet>91</a>
<a href=#92 id=92 data-nosnippet>92</a> <span class="attr">#[test]
<a href=#93 id=93 data-nosnippet>93</a> </span><span class="kw">pub fn </span>test_set_timezone() {
<a href=#94 id=94 data-nosnippet>94</a> <span class="kw">let </span>expected_utc_expr = Expr::Value(Value::SingleQuotedString(<span class="string">"UTC"</span>.to_string()).into());
<a href=#95 id=95 data-nosnippet>95</a> <span class="comment">// mysql style
<a href=#96 id=96 data-nosnippet>96</a> </span><span class="kw">let </span>sql = <span class="string">"SET time_zone = 'UTC'"</span>;
<a href=#97 id=97 data-nosnippet>97</a> assert_mysql_parse_result(sql, <span class="string">"time_zone"</span>, expected_utc_expr.clone());
<a href=#98 id=98 data-nosnippet>98</a> <span class="comment">// session or local style
<a href=#99 id=99 data-nosnippet>99</a> </span><span class="kw">let </span>sql = <span class="string">"SET LOCAL time_zone = 'UTC'"</span>;
<a href=#100 id=100 data-nosnippet>100</a> assert_mysql_parse_result(sql, <span class="string">"time_zone"</span>, expected_utc_expr.clone());
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">let </span>sql = <span class="string">"SET SESSION time_zone = 'UTC'"</span>;
<a href=#102 id=102 data-nosnippet>102</a> assert_mysql_parse_result(sql, <span class="string">"time_zone"</span>, expected_utc_expr.clone());
<a href=#103 id=103 data-nosnippet>103</a>
<a href=#104 id=104 data-nosnippet>104</a> <span class="comment">// postgresql style
<a href=#105 id=105 data-nosnippet>105</a> </span><span class="kw">let </span>sql = <span class="string">"SET TIMEZONE TO 'UTC'"</span>;
<a href=#106 id=106 data-nosnippet>106</a> assert_pg_parse_result(sql, <span class="string">"TIMEZONE"</span>, expected_utc_expr.clone());
<a href=#107 id=107 data-nosnippet>107</a> <span class="kw">let </span>sql = <span class="string">"SET TIMEZONE 'UTC'"</span>;
<a href=#108 id=108 data-nosnippet>108</a> assert_pg_parse_result(sql, <span class="string">"TIMEZONE"</span>, expected_utc_expr);
<a href=#109 id=109 data-nosnippet>109</a> }
<a href=#110 id=110 data-nosnippet>110</a>
<a href=#111 id=111 data-nosnippet>111</a> <span class="attr">#[test]
<a href=#112 id=112 data-nosnippet>112</a> </span><span class="kw">pub fn </span>test_set_query_timeout() {
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">let </span>expected_query_timeout_expr =
<a href=#114 id=114 data-nosnippet>114</a> Expr::Value(Value::Number(<span class="string">"5000"</span>.to_string(), <span class="bool-val">false</span>).into());
<a href=#115 id=115 data-nosnippet>115</a> <span class="comment">// mysql style
<a href=#116 id=116 data-nosnippet>116</a> </span><span class="kw">let </span>sql = <span class="string">"SET MAX_EXECUTION_TIME = 5000"</span>;
<a href=#117 id=117 data-nosnippet>117</a> assert_mysql_parse_result(
<a href=#118 id=118 data-nosnippet>118</a> sql,
<a href=#119 id=119 data-nosnippet>119</a> <span class="string">"MAX_EXECUTION_TIME"</span>,
<a href=#120 id=120 data-nosnippet>120</a> expected_query_timeout_expr.clone(),
<a href=#121 id=121 data-nosnippet>121</a> );
<a href=#122 id=122 data-nosnippet>122</a> <span class="comment">// session or local style
<a href=#123 id=123 data-nosnippet>123</a> </span><span class="kw">let </span>sql = <span class="string">"SET LOCAL MAX_EXECUTION_TIME = 5000"</span>;
<a href=#124 id=124 data-nosnippet>124</a> assert_mysql_parse_result(
<a href=#125 id=125 data-nosnippet>125</a> sql,
<a href=#126 id=126 data-nosnippet>126</a> <span class="string">"MAX_EXECUTION_TIME"</span>,
<a href=#127 id=127 data-nosnippet>127</a> expected_query_timeout_expr.clone(),
<a href=#128 id=128 data-nosnippet>128</a> );
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">let </span>sql = <span class="string">"SET SESSION MAX_EXECUTION_TIME = 5000"</span>;
<a href=#130 id=130 data-nosnippet>130</a> assert_mysql_parse_result(
<a href=#131 id=131 data-nosnippet>131</a> sql,
<a href=#132 id=132 data-nosnippet>132</a> <span class="string">"MAX_EXECUTION_TIME"</span>,
<a href=#133 id=133 data-nosnippet>133</a> expected_query_timeout_expr.clone(),
<a href=#134 id=134 data-nosnippet>134</a> );
<a href=#135 id=135 data-nosnippet>135</a>
<a href=#136 id=136 data-nosnippet>136</a> <span class="comment">// postgresql style
<a href=#137 id=137 data-nosnippet>137</a> </span><span class="kw">let </span>sql = <span class="string">"SET STATEMENT_TIMEOUT = 5000"</span>;
<a href=#138 id=138 data-nosnippet>138</a> assert_pg_parse_result(
<a href=#139 id=139 data-nosnippet>139</a> sql,
<a href=#140 id=140 data-nosnippet>140</a> <span class="string">"STATEMENT_TIMEOUT"</span>,
<a href=#141 id=141 data-nosnippet>141</a> expected_query_timeout_expr.clone(),
<a href=#142 id=142 data-nosnippet>142</a> );
<a href=#143 id=143 data-nosnippet>143</a> <span class="kw">let </span>sql = <span class="string">"SET STATEMENT_TIMEOUT TO 5000"</span>;
<a href=#144 id=144 data-nosnippet>144</a> assert_pg_parse_result(sql, <span class="string">"STATEMENT_TIMEOUT"</span>, expected_query_timeout_expr);
<a href=#145 id=145 data-nosnippet>145</a> }
<a href=#146 id=146 data-nosnippet>146</a>
<a href=#147 id=147 data-nosnippet>147</a> <span class="attr">#[test]
<a href=#148 id=148 data-nosnippet>148</a> </span><span class="kw">fn </span>test_unsupported_set_variant_remains_rejected() {
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw">let </span>result = ParserContext::create_with_dialect(
<a href=#150 id=150 data-nosnippet>150</a> <span class="string">"SET ROLE admin"</span>,
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#152 id=152 data-nosnippet>152</a> ParseOptions::default(),
<a href=#153 id=153 data-nosnippet>153</a> );
<a href=#154 id=154 data-nosnippet>154</a> <span class="macro">assert!</span>(result.is_err());
<a href=#155 id=155 data-nosnippet>155</a> }
<a href=#156 id=156 data-nosnippet>156</a>}
</code></pre></div></section></main></body></html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+468
View File
@@ -0,0 +1,468 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/truncate_parser.rs`."><title>truncate_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>truncate_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, InvalidSqlSnafu, InvalidTableNameSnafu, <span class="prelude-ty">Result</span>, UnexpectedTokenSnafu};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::statements::truncate::TruncateTable;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="doccomment">/// `TRUNCATE [TABLE] table_name;`
<a href=#25 id=25 data-nosnippet>25</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#26 id=26 data-nosnippet>26</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_truncate(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.next_token();
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">let _ </span>= <span class="self">self</span>.parser.parse_keyword(Keyword::TABLE);
<a href=#29 id=29 data-nosnippet>29</a>
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">let </span>raw_table_ident =
<a href=#31 id=31 data-nosnippet>31</a> <span class="self">self</span>.parse_object_name()
<a href=#32 id=32 data-nosnippet>32</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#33 id=33 data-nosnippet>33</a> expected: <span class="string">"a table name"</span>,
<a href=#34 id=34 data-nosnippet>34</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#35 id=35 data-nosnippet>35</a> })<span class="question-mark">?</span>;
<a href=#36 id=36 data-nosnippet>36</a> <span class="kw">let </span>table_ident = <span class="self">Self</span>::canonicalize_object_name(raw_table_ident)<span class="question-mark">?</span>;
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a> <span class="macro">ensure!</span>(
<a href=#39 id=39 data-nosnippet>39</a> !table_ident.<span class="number">0</span>.is_empty(),
<a href=#40 id=40 data-nosnippet>40</a> InvalidTableNameSnafu {
<a href=#41 id=41 data-nosnippet>41</a> name: table_ident.to_string()
<a href=#42 id=42 data-nosnippet>42</a> }
<a href=#43 id=43 data-nosnippet>43</a> );
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a> <span class="kw">let </span>have_range = <span class="self">self</span>.parser.parse_keywords(<span class="kw-2">&amp;</span>[Keyword::FILE, Keyword::RANGE]);
<a href=#46 id=46 data-nosnippet>46</a>
<a href=#47 id=47 data-nosnippet>47</a> <span class="comment">// if no range is specified, we just truncate the table
<a href=#48 id=48 data-nosnippet>48</a> </span><span class="kw">if </span>!have_range {
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(Statement::TruncateTable(TruncateTable::new(table_ident)));
<a href=#50 id=50 data-nosnippet>50</a> }
<a href=#51 id=51 data-nosnippet>51</a>
<a href=#52 id=52 data-nosnippet>52</a> <span class="comment">// parse a list of time ranges consist of (Timestamp, Timestamp),?
<a href=#53 id=53 data-nosnippet>53</a> </span><span class="kw">let </span><span class="kw-2">mut </span>time_ranges = <span class="macro">vec!</span>[];
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">loop </span>{
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">let _ </span>= <span class="self">self
<a href=#56 id=56 data-nosnippet>56</a> </span>.parser
<a href=#57 id=57 data-nosnippet>57</a> .expect_token(<span class="kw-2">&amp;</span>sqlparser::tokenizer::Token::LParen)
<a href=#58 id=58 data-nosnippet>58</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#59 id=59 data-nosnippet>59</a> expected: <span class="string">"a left parenthesis"</span>,
<a href=#60 id=60 data-nosnippet>60</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#61 id=61 data-nosnippet>61</a> })<span class="question-mark">?</span>;
<a href=#62 id=62 data-nosnippet>62</a>
<a href=#63 id=63 data-nosnippet>63</a> <span class="comment">// parse to values here, no need to valid in parser
<a href=#64 id=64 data-nosnippet>64</a> </span><span class="kw">let </span>start = <span class="self">self
<a href=#65 id=65 data-nosnippet>65</a> </span>.parser
<a href=#66 id=66 data-nosnippet>66</a> .parse_value()
<a href=#67 id=67 data-nosnippet>67</a> .map(|x| x.value)
<a href=#68 id=68 data-nosnippet>68</a> .with_context(|e| error::UnexpectedSnafu {
<a href=#69 id=69 data-nosnippet>69</a> expected: <span class="string">"a timestamp value"</span>,
<a href=#70 id=70 data-nosnippet>70</a> actual: e.to_string(),
<a href=#71 id=71 data-nosnippet>71</a> })<span class="question-mark">?</span>;
<a href=#72 id=72 data-nosnippet>72</a>
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">let _ </span>= <span class="self">self
<a href=#74 id=74 data-nosnippet>74</a> </span>.parser
<a href=#75 id=75 data-nosnippet>75</a> .expect_token(<span class="kw-2">&amp;</span>sqlparser::tokenizer::Token::Comma)
<a href=#76 id=76 data-nosnippet>76</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#77 id=77 data-nosnippet>77</a> expected: <span class="string">"a comma"</span>,
<a href=#78 id=78 data-nosnippet>78</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#79 id=79 data-nosnippet>79</a> })<span class="question-mark">?</span>;
<a href=#80 id=80 data-nosnippet>80</a>
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">let </span>end = <span class="self">self
<a href=#82 id=82 data-nosnippet>82</a> </span>.parser
<a href=#83 id=83 data-nosnippet>83</a> .parse_value()
<a href=#84 id=84 data-nosnippet>84</a> .map(|x| x.value)
<a href=#85 id=85 data-nosnippet>85</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#86 id=86 data-nosnippet>86</a> expected: <span class="string">"a timestamp"</span>,
<a href=#87 id=87 data-nosnippet>87</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#88 id=88 data-nosnippet>88</a> })<span class="question-mark">?</span>;
<a href=#89 id=89 data-nosnippet>89</a>
<a href=#90 id=90 data-nosnippet>90</a> <span class="kw">let _ </span>= <span class="self">self
<a href=#91 id=91 data-nosnippet>91</a> </span>.parser
<a href=#92 id=92 data-nosnippet>92</a> .expect_token(<span class="kw-2">&amp;</span>sqlparser::tokenizer::Token::RParen)
<a href=#93 id=93 data-nosnippet>93</a> .with_context(|<span class="kw">_</span>| error::UnexpectedSnafu {
<a href=#94 id=94 data-nosnippet>94</a> expected: <span class="string">"a right parenthesis"</span>,
<a href=#95 id=95 data-nosnippet>95</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#96 id=96 data-nosnippet>96</a> })<span class="question-mark">?</span>;
<a href=#97 id=97 data-nosnippet>97</a>
<a href=#98 id=98 data-nosnippet>98</a> time_ranges.push((start, end));
<a href=#99 id=99 data-nosnippet>99</a>
<a href=#100 id=100 data-nosnippet>100</a> <span class="kw">let </span>peek = <span class="self">self</span>.parser.peek_token().token;
<a href=#101 id=101 data-nosnippet>101</a>
<a href=#102 id=102 data-nosnippet>102</a> <span class="kw">match </span>peek {
<a href=#103 id=103 data-nosnippet>103</a> sqlparser::tokenizer::Token::EOF | Token::SemiColon =&gt; {
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">if </span>time_ranges.is_empty() {
<a href=#105 id=105 data-nosnippet>105</a> <span class="kw">return </span><span class="prelude-val">Err</span>(InvalidSqlSnafu {
<a href=#106 id=106 data-nosnippet>106</a> msg: <span class="string">"TRUNCATE TABLE RANGE must have at least one range"</span>.to_string(),
<a href=#107 id=107 data-nosnippet>107</a> }
<a href=#108 id=108 data-nosnippet>108</a> .build());
<a href=#109 id=109 data-nosnippet>109</a> }
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">break</span>;
<a href=#111 id=111 data-nosnippet>111</a> }
<a href=#112 id=112 data-nosnippet>112</a> Token::Comma =&gt; {
<a href=#113 id=113 data-nosnippet>113</a> <span class="self">self</span>.parser.next_token(); <span class="comment">// Consume the comma
<a href=#114 id=114 data-nosnippet>114</a> </span><span class="kw">let </span>next_peek = <span class="self">self</span>.parser.peek_token().token; <span class="comment">// Peek the token after the comma
<a href=#115 id=115 data-nosnippet>115</a> </span><span class="kw">if </span><span class="macro">matches!</span>(next_peek, Token::EOF | Token::SemiColon) {
<a href=#116 id=116 data-nosnippet>116</a> <span class="kw">break</span>; <span class="comment">// Trailing comma, end of statement
<a href=#117 id=117 data-nosnippet>117</a> </span>}
<a href=#118 id=118 data-nosnippet>118</a> <span class="comment">// Otherwise, continue to parse next range
<a href=#119 id=119 data-nosnippet>119</a> </span><span class="kw">continue</span>;
<a href=#120 id=120 data-nosnippet>120</a> }
<a href=#121 id=121 data-nosnippet>121</a> <span class="kw">_ </span>=&gt; UnexpectedTokenSnafu {
<a href=#122 id=122 data-nosnippet>122</a> expected: <span class="string">"a comma or end of statement"</span>,
<a href=#123 id=123 data-nosnippet>123</a> actual: <span class="self">self</span>.peek_token_as_string(),
<a href=#124 id=124 data-nosnippet>124</a> }
<a href=#125 id=125 data-nosnippet>125</a> .fail()<span class="question-mark">?</span>,
<a href=#126 id=126 data-nosnippet>126</a> }
<a href=#127 id=127 data-nosnippet>127</a> }
<a href=#128 id=128 data-nosnippet>128</a>
<a href=#129 id=129 data-nosnippet>129</a> <span class="prelude-val">Ok</span>(Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#130 id=130 data-nosnippet>130</a> table_ident,
<a href=#131 id=131 data-nosnippet>131</a> time_ranges,
<a href=#132 id=132 data-nosnippet>132</a> )))
<a href=#133 id=133 data-nosnippet>133</a> }
<a href=#134 id=134 data-nosnippet>134</a>}
<a href=#135 id=135 data-nosnippet>135</a>
<a href=#136 id=136 data-nosnippet>136</a><span class="attr">#[cfg(test)]
<a href=#137 id=137 data-nosnippet>137</a></span><span class="kw">mod </span>tests {
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">use </span>sqlparser::ast::{Ident, ObjectName};
<a href=#139 id=139 data-nosnippet>139</a>
<a href=#140 id=140 data-nosnippet>140</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#142 id=142 data-nosnippet>142</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParseOptions;
<a href=#143 id=143 data-nosnippet>143</a>
<a href=#144 id=144 data-nosnippet>144</a> <span class="attr">#[test]
<a href=#145 id=145 data-nosnippet>145</a> </span><span class="kw">pub fn </span>test_parse_truncate_with_ranges() {
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">let </span>sql = <span class="string">r#"TRUNCATE foo FILE RANGE (0, 20)"#</span>;
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#148 id=148 data-nosnippet>148</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#149 id=149 data-nosnippet>149</a> .unwrap();
<a href=#150 id=150 data-nosnippet>150</a> <span class="macro">assert_eq!</span>(
<a href=#151 id=151 data-nosnippet>151</a> stmts.pop().unwrap(),
<a href=#152 id=152 data-nosnippet>152</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#153 id=153 data-nosnippet>153</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)]),
<a href=#154 id=154 data-nosnippet>154</a> <span class="macro">vec!</span>[(
<a href=#155 id=155 data-nosnippet>155</a> sqlparser::ast::Value::Number(<span class="string">"0"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#156 id=156 data-nosnippet>156</a> sqlparser::ast::Value::Number(<span class="string">"20"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#157 id=157 data-nosnippet>157</a> )]
<a href=#158 id=158 data-nosnippet>158</a> ))
<a href=#159 id=159 data-nosnippet>159</a> );
<a href=#160 id=160 data-nosnippet>160</a>
<a href=#161 id=161 data-nosnippet>161</a> <span class="kw">let </span>sql = <span class="string">r#"TRUNCATE TABLE foo FILE RANGE ("2000-01-01 00:00:00+00:00", "2000-01-01 00:00:00+00:00"), (2,33)"#</span>;
<a href=#162 id=162 data-nosnippet>162</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#163 id=163 data-nosnippet>163</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#164 id=164 data-nosnippet>164</a> .unwrap();
<a href=#165 id=165 data-nosnippet>165</a> <span class="macro">assert_eq!</span>(
<a href=#166 id=166 data-nosnippet>166</a> stmts.pop().unwrap(),
<a href=#167 id=167 data-nosnippet>167</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#168 id=168 data-nosnippet>168</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"foo"</span>)]),
<a href=#169 id=169 data-nosnippet>169</a> <span class="macro">vec!</span>[
<a href=#170 id=170 data-nosnippet>170</a> (
<a href=#171 id=171 data-nosnippet>171</a> sqlparser::ast::Value::DoubleQuotedString(
<a href=#172 id=172 data-nosnippet>172</a> <span class="string">"2000-01-01 00:00:00+00:00"</span>.to_string()
<a href=#173 id=173 data-nosnippet>173</a> ),
<a href=#174 id=174 data-nosnippet>174</a> sqlparser::ast::Value::DoubleQuotedString(
<a href=#175 id=175 data-nosnippet>175</a> <span class="string">"2000-01-01 00:00:00+00:00"</span>.to_string()
<a href=#176 id=176 data-nosnippet>176</a> )
<a href=#177 id=177 data-nosnippet>177</a> ),
<a href=#178 id=178 data-nosnippet>178</a> (
<a href=#179 id=179 data-nosnippet>179</a> sqlparser::ast::Value::Number(<span class="string">"2"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#180 id=180 data-nosnippet>180</a> sqlparser::ast::Value::Number(<span class="string">"33"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#181 id=181 data-nosnippet>181</a> )
<a href=#182 id=182 data-nosnippet>182</a> ]
<a href=#183 id=183 data-nosnippet>183</a> ))
<a href=#184 id=184 data-nosnippet>184</a> );
<a href=#185 id=185 data-nosnippet>185</a>
<a href=#186 id=186 data-nosnippet>186</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE my_schema.foo FILE RANGE (1, 2), (3, 4),"</span>;
<a href=#187 id=187 data-nosnippet>187</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#188 id=188 data-nosnippet>188</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#189 id=189 data-nosnippet>189</a> .unwrap();
<a href=#190 id=190 data-nosnippet>190</a> <span class="macro">assert_eq!</span>(
<a href=#191 id=191 data-nosnippet>191</a> stmts.pop().unwrap(),
<a href=#192 id=192 data-nosnippet>192</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#193 id=193 data-nosnippet>193</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"my_schema"</span>), Ident::new(<span class="string">"foo"</span>)]),
<a href=#194 id=194 data-nosnippet>194</a> <span class="macro">vec!</span>[
<a href=#195 id=195 data-nosnippet>195</a> (
<a href=#196 id=196 data-nosnippet>196</a> sqlparser::ast::Value::Number(<span class="string">"1"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#197 id=197 data-nosnippet>197</a> sqlparser::ast::Value::Number(<span class="string">"2"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#198 id=198 data-nosnippet>198</a> ),
<a href=#199 id=199 data-nosnippet>199</a> (
<a href=#200 id=200 data-nosnippet>200</a> sqlparser::ast::Value::Number(<span class="string">"3"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#201 id=201 data-nosnippet>201</a> sqlparser::ast::Value::Number(<span class="string">"4"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#202 id=202 data-nosnippet>202</a> )
<a href=#203 id=203 data-nosnippet>203</a> ]
<a href=#204 id=204 data-nosnippet>204</a> ))
<a href=#205 id=205 data-nosnippet>205</a> );
<a href=#206 id=206 data-nosnippet>206</a>
<a href=#207 id=207 data-nosnippet>207</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE my_schema.foo FILE RANGE (1,2),"</span>;
<a href=#208 id=208 data-nosnippet>208</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#209 id=209 data-nosnippet>209</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#210 id=210 data-nosnippet>210</a> .unwrap();
<a href=#211 id=211 data-nosnippet>211</a> <span class="macro">assert_eq!</span>(
<a href=#212 id=212 data-nosnippet>212</a> stmts.pop().unwrap(),
<a href=#213 id=213 data-nosnippet>213</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#214 id=214 data-nosnippet>214</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"my_schema"</span>), Ident::new(<span class="string">"foo"</span>)]),
<a href=#215 id=215 data-nosnippet>215</a> <span class="macro">vec!</span>[(
<a href=#216 id=216 data-nosnippet>216</a> sqlparser::ast::Value::Number(<span class="string">"1"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#217 id=217 data-nosnippet>217</a> sqlparser::ast::Value::Number(<span class="string">"2"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#218 id=218 data-nosnippet>218</a> )]
<a href=#219 id=219 data-nosnippet>219</a> ))
<a href=#220 id=220 data-nosnippet>220</a> );
<a href=#221 id=221 data-nosnippet>221</a>
<a href=#222 id=222 data-nosnippet>222</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE my_catalog.my_schema.foo FILE RANGE (1,2);"</span>;
<a href=#223 id=223 data-nosnippet>223</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#224 id=224 data-nosnippet>224</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#225 id=225 data-nosnippet>225</a> .unwrap();
<a href=#226 id=226 data-nosnippet>226</a> <span class="macro">assert_eq!</span>(
<a href=#227 id=227 data-nosnippet>227</a> stmts.pop().unwrap(),
<a href=#228 id=228 data-nosnippet>228</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#229 id=229 data-nosnippet>229</a> ObjectName::from(<span class="macro">vec!</span>[
<a href=#230 id=230 data-nosnippet>230</a> Ident::new(<span class="string">"my_catalog"</span>),
<a href=#231 id=231 data-nosnippet>231</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#232 id=232 data-nosnippet>232</a> Ident::new(<span class="string">"foo"</span>)
<a href=#233 id=233 data-nosnippet>233</a> ]),
<a href=#234 id=234 data-nosnippet>234</a> <span class="macro">vec!</span>[(
<a href=#235 id=235 data-nosnippet>235</a> sqlparser::ast::Value::Number(<span class="string">"1"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#236 id=236 data-nosnippet>236</a> sqlparser::ast::Value::Number(<span class="string">"2"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#237 id=237 data-nosnippet>237</a> )]
<a href=#238 id=238 data-nosnippet>238</a> ))
<a href=#239 id=239 data-nosnippet>239</a> );
<a href=#240 id=240 data-nosnippet>240</a>
<a href=#241 id=241 data-nosnippet>241</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE drop FILE RANGE (1,2)"</span>;
<a href=#242 id=242 data-nosnippet>242</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#243 id=243 data-nosnippet>243</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#244 id=244 data-nosnippet>244</a> .unwrap();
<a href=#245 id=245 data-nosnippet>245</a> <span class="macro">assert_eq!</span>(
<a href=#246 id=246 data-nosnippet>246</a> stmts.pop().unwrap(),
<a href=#247 id=247 data-nosnippet>247</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#248 id=248 data-nosnippet>248</a> ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"drop"</span>)]),
<a href=#249 id=249 data-nosnippet>249</a> <span class="macro">vec!</span>[(
<a href=#250 id=250 data-nosnippet>250</a> sqlparser::ast::Value::Number(<span class="string">"1"</span>.to_string(), <span class="bool-val">false</span>),
<a href=#251 id=251 data-nosnippet>251</a> sqlparser::ast::Value::Number(<span class="string">"2"</span>.to_string(), <span class="bool-val">false</span>)
<a href=#252 id=252 data-nosnippet>252</a> )]
<a href=#253 id=253 data-nosnippet>253</a> ))
<a href=#254 id=254 data-nosnippet>254</a> );
<a href=#255 id=255 data-nosnippet>255</a>
<a href=#256 id=256 data-nosnippet>256</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE `drop`"</span>;
<a href=#257 id=257 data-nosnippet>257</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#258 id=258 data-nosnippet>258</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#259 id=259 data-nosnippet>259</a> .unwrap();
<a href=#260 id=260 data-nosnippet>260</a> <span class="macro">assert_eq!</span>(
<a href=#261 id=261 data-nosnippet>261</a> stmts.pop().unwrap(),
<a href=#262 id=262 data-nosnippet>262</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[
<a href=#263 id=263 data-nosnippet>263</a> Ident::with_quote(<span class="string">'`'</span>, <span class="string">"drop"</span>),
<a href=#264 id=264 data-nosnippet>264</a> ])))
<a href=#265 id=265 data-nosnippet>265</a> );
<a href=#266 id=266 data-nosnippet>266</a>
<a href=#267 id=267 data-nosnippet>267</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE \"drop\" FILE RANGE (\"1\", \"2\")"</span>;
<a href=#268 id=268 data-nosnippet>268</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#269 id=269 data-nosnippet>269</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#270 id=270 data-nosnippet>270</a> .unwrap();
<a href=#271 id=271 data-nosnippet>271</a> <span class="macro">assert_eq!</span>(
<a href=#272 id=272 data-nosnippet>272</a> stmts.pop().unwrap(),
<a href=#273 id=273 data-nosnippet>273</a> Statement::TruncateTable(TruncateTable::new_with_ranges(
<a href=#274 id=274 data-nosnippet>274</a> ObjectName::from(<span class="macro">vec!</span>[Ident::with_quote(<span class="string">'"'</span>, <span class="string">"drop"</span>)]),
<a href=#275 id=275 data-nosnippet>275</a> <span class="macro">vec!</span>[(
<a href=#276 id=276 data-nosnippet>276</a> sqlparser::ast::Value::DoubleQuotedString(<span class="string">"1"</span>.to_string()),
<a href=#277 id=277 data-nosnippet>277</a> sqlparser::ast::Value::DoubleQuotedString(<span class="string">"2"</span>.to_string())
<a href=#278 id=278 data-nosnippet>278</a> )]
<a href=#279 id=279 data-nosnippet>279</a> ))
<a href=#280 id=280 data-nosnippet>280</a> );
<a href=#281 id=281 data-nosnippet>281</a> }
<a href=#282 id=282 data-nosnippet>282</a>
<a href=#283 id=283 data-nosnippet>283</a> <span class="attr">#[test]
<a href=#284 id=284 data-nosnippet>284</a> </span><span class="kw">pub fn </span>test_parse_truncate() {
<a href=#285 id=285 data-nosnippet>285</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE foo"</span>;
<a href=#286 id=286 data-nosnippet>286</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#287 id=287 data-nosnippet>287</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#288 id=288 data-nosnippet>288</a> .unwrap();
<a href=#289 id=289 data-nosnippet>289</a> <span class="macro">assert_eq!</span>(
<a href=#290 id=290 data-nosnippet>290</a> stmts.pop().unwrap(),
<a href=#291 id=291 data-nosnippet>291</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[Ident::new(
<a href=#292 id=292 data-nosnippet>292</a> <span class="string">"foo"
<a href=#293 id=293 data-nosnippet>293</a> </span>)])))
<a href=#294 id=294 data-nosnippet>294</a> );
<a href=#295 id=295 data-nosnippet>295</a>
<a href=#296 id=296 data-nosnippet>296</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo"</span>;
<a href=#297 id=297 data-nosnippet>297</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#298 id=298 data-nosnippet>298</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#299 id=299 data-nosnippet>299</a> .unwrap();
<a href=#300 id=300 data-nosnippet>300</a> <span class="macro">assert_eq!</span>(
<a href=#301 id=301 data-nosnippet>301</a> stmts.pop().unwrap(),
<a href=#302 id=302 data-nosnippet>302</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[Ident::new(
<a href=#303 id=303 data-nosnippet>303</a> <span class="string">"foo"
<a href=#304 id=304 data-nosnippet>304</a> </span>)])))
<a href=#305 id=305 data-nosnippet>305</a> );
<a href=#306 id=306 data-nosnippet>306</a>
<a href=#307 id=307 data-nosnippet>307</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE my_schema.foo"</span>;
<a href=#308 id=308 data-nosnippet>308</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#309 id=309 data-nosnippet>309</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#310 id=310 data-nosnippet>310</a> .unwrap();
<a href=#311 id=311 data-nosnippet>311</a> <span class="macro">assert_eq!</span>(
<a href=#312 id=312 data-nosnippet>312</a> stmts.pop().unwrap(),
<a href=#313 id=313 data-nosnippet>313</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[
<a href=#314 id=314 data-nosnippet>314</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#315 id=315 data-nosnippet>315</a> Ident::new(<span class="string">"foo"</span>)
<a href=#316 id=316 data-nosnippet>316</a> ])))
<a href=#317 id=317 data-nosnippet>317</a> );
<a href=#318 id=318 data-nosnippet>318</a>
<a href=#319 id=319 data-nosnippet>319</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE my_schema.foo"</span>;
<a href=#320 id=320 data-nosnippet>320</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#321 id=321 data-nosnippet>321</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#322 id=322 data-nosnippet>322</a> .unwrap();
<a href=#323 id=323 data-nosnippet>323</a> <span class="macro">assert_eq!</span>(
<a href=#324 id=324 data-nosnippet>324</a> stmts.pop().unwrap(),
<a href=#325 id=325 data-nosnippet>325</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[
<a href=#326 id=326 data-nosnippet>326</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#327 id=327 data-nosnippet>327</a> Ident::new(<span class="string">"foo"</span>)
<a href=#328 id=328 data-nosnippet>328</a> ])))
<a href=#329 id=329 data-nosnippet>329</a> );
<a href=#330 id=330 data-nosnippet>330</a>
<a href=#331 id=331 data-nosnippet>331</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE my_catalog.my_schema.foo"</span>;
<a href=#332 id=332 data-nosnippet>332</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#333 id=333 data-nosnippet>333</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#334 id=334 data-nosnippet>334</a> .unwrap();
<a href=#335 id=335 data-nosnippet>335</a> <span class="macro">assert_eq!</span>(
<a href=#336 id=336 data-nosnippet>336</a> stmts.pop().unwrap(),
<a href=#337 id=337 data-nosnippet>337</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[
<a href=#338 id=338 data-nosnippet>338</a> Ident::new(<span class="string">"my_catalog"</span>),
<a href=#339 id=339 data-nosnippet>339</a> Ident::new(<span class="string">"my_schema"</span>),
<a href=#340 id=340 data-nosnippet>340</a> Ident::new(<span class="string">"foo"</span>)
<a href=#341 id=341 data-nosnippet>341</a> ])))
<a href=#342 id=342 data-nosnippet>342</a> );
<a href=#343 id=343 data-nosnippet>343</a>
<a href=#344 id=344 data-nosnippet>344</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE drop"</span>;
<a href=#345 id=345 data-nosnippet>345</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#346 id=346 data-nosnippet>346</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#347 id=347 data-nosnippet>347</a> .unwrap();
<a href=#348 id=348 data-nosnippet>348</a> <span class="macro">assert_eq!</span>(
<a href=#349 id=349 data-nosnippet>349</a> stmts.pop().unwrap(),
<a href=#350 id=350 data-nosnippet>350</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[Ident::new(
<a href=#351 id=351 data-nosnippet>351</a> <span class="string">"drop"
<a href=#352 id=352 data-nosnippet>352</a> </span>)])))
<a href=#353 id=353 data-nosnippet>353</a> );
<a href=#354 id=354 data-nosnippet>354</a>
<a href=#355 id=355 data-nosnippet>355</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE `drop`"</span>;
<a href=#356 id=356 data-nosnippet>356</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#357 id=357 data-nosnippet>357</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#358 id=358 data-nosnippet>358</a> .unwrap();
<a href=#359 id=359 data-nosnippet>359</a> <span class="macro">assert_eq!</span>(
<a href=#360 id=360 data-nosnippet>360</a> stmts.pop().unwrap(),
<a href=#361 id=361 data-nosnippet>361</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[
<a href=#362 id=362 data-nosnippet>362</a> Ident::with_quote(<span class="string">'`'</span>, <span class="string">"drop"</span>),
<a href=#363 id=363 data-nosnippet>363</a> ])))
<a href=#364 id=364 data-nosnippet>364</a> );
<a href=#365 id=365 data-nosnippet>365</a>
<a href=#366 id=366 data-nosnippet>366</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE \"drop\""</span>;
<a href=#367 id=367 data-nosnippet>367</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#368 id=368 data-nosnippet>368</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#369 id=369 data-nosnippet>369</a> .unwrap();
<a href=#370 id=370 data-nosnippet>370</a> <span class="macro">assert_eq!</span>(
<a href=#371 id=371 data-nosnippet>371</a> stmts.pop().unwrap(),
<a href=#372 id=372 data-nosnippet>372</a> Statement::TruncateTable(TruncateTable::new(ObjectName::from(<span class="macro">vec!</span>[
<a href=#373 id=373 data-nosnippet>373</a> Ident::with_quote(<span class="string">'"'</span>, <span class="string">"drop"</span>),
<a href=#374 id=374 data-nosnippet>374</a> ])))
<a href=#375 id=375 data-nosnippet>375</a> );
<a href=#376 id=376 data-nosnippet>376</a> }
<a href=#377 id=377 data-nosnippet>377</a>
<a href=#378 id=378 data-nosnippet>378</a> <span class="attr">#[test]
<a href=#379 id=379 data-nosnippet>379</a> </span><span class="kw">pub fn </span>test_parse_invalid_truncate() {
<a href=#380 id=380 data-nosnippet>380</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE SCHEMA foo"</span>;
<a href=#381 id=381 data-nosnippet>381</a> <span class="kw">let </span>result =
<a href=#382 id=382 data-nosnippet>382</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#383 id=383 data-nosnippet>383</a> <span class="macro">assert!</span>(result.is_err(), <span class="string">"result is: {result:?}"</span>);
<a href=#384 id=384 data-nosnippet>384</a>
<a href=#385 id=385 data-nosnippet>385</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE"</span>;
<a href=#386 id=386 data-nosnippet>386</a> <span class="kw">let </span>result =
<a href=#387 id=387 data-nosnippet>387</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#388 id=388 data-nosnippet>388</a> <span class="macro">assert!</span>(result.is_err(), <span class="string">"result is: {result:?}"</span>);
<a href=#389 id=389 data-nosnippet>389</a>
<a href=#390 id=390 data-nosnippet>390</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo RANGE"</span>;
<a href=#391 id=391 data-nosnippet>391</a> <span class="kw">let </span>result =
<a href=#392 id=392 data-nosnippet>392</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#393 id=393 data-nosnippet>393</a> <span class="macro">assert!</span>(
<a href=#394 id=394 data-nosnippet>394</a> result.is_err()
<a href=#395 id=395 data-nosnippet>395</a> &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"SQL statement is not supported, keyword: RANGE"</span>),
<a href=#396 id=396 data-nosnippet>396</a> <span class="string">"result is: {result:?}"
<a href=#397 id=397 data-nosnippet>397</a> </span>);
<a href=#398 id=398 data-nosnippet>398</a>
<a href=#399 id=399 data-nosnippet>399</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE"</span>;
<a href=#400 id=400 data-nosnippet>400</a> <span class="kw">let </span>result =
<a href=#401 id=401 data-nosnippet>401</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#402 id=402 data-nosnippet>402</a> <span class="macro">assert!</span>(
<a href=#403 id=403 data-nosnippet>403</a> result.is_err()
<a href=#404 id=404 data-nosnippet>404</a> &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"SQL statement is not supported, keyword: FILE"</span>),
<a href=#405 id=405 data-nosnippet>405</a> <span class="string">"result is: {result:?}"
<a href=#406 id=406 data-nosnippet>406</a> </span>);
<a href=#407 id=407 data-nosnippet>407</a>
<a href=#408 id=408 data-nosnippet>408</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE"</span>;
<a href=#409 id=409 data-nosnippet>409</a> <span class="kw">let </span>result =
<a href=#410 id=410 data-nosnippet>410</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#411 id=411 data-nosnippet>411</a> <span class="macro">assert!</span>(
<a href=#412 id=412 data-nosnippet>412</a> result.is_err() &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"expected: 'a left parenthesis'"</span>),
<a href=#413 id=413 data-nosnippet>413</a> <span class="string">"result is: {result:?}"
<a href=#414 id=414 data-nosnippet>414</a> </span>);
<a href=#415 id=415 data-nosnippet>415</a>
<a href=#416 id=416 data-nosnippet>416</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE ("</span>;
<a href=#417 id=417 data-nosnippet>417</a> <span class="kw">let </span>result =
<a href=#418 id=418 data-nosnippet>418</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#419 id=419 data-nosnippet>419</a> <span class="macro">assert!</span>(
<a href=#420 id=420 data-nosnippet>420</a> result.is_err() &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"expected: 'a timestamp value'"</span>),
<a href=#421 id=421 data-nosnippet>421</a> <span class="string">"result is: {result:?}"
<a href=#422 id=422 data-nosnippet>422</a> </span>);
<a href=#423 id=423 data-nosnippet>423</a>
<a href=#424 id=424 data-nosnippet>424</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE ()"</span>;
<a href=#425 id=425 data-nosnippet>425</a> <span class="kw">let </span>result =
<a href=#426 id=426 data-nosnippet>426</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#427 id=427 data-nosnippet>427</a> <span class="macro">assert!</span>(
<a href=#428 id=428 data-nosnippet>428</a> result.is_err() &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"expected: 'a timestamp value'"</span>),
<a href=#429 id=429 data-nosnippet>429</a> <span class="string">"result is: {result:?}"
<a href=#430 id=430 data-nosnippet>430</a> </span>);
<a href=#431 id=431 data-nosnippet>431</a>
<a href=#432 id=432 data-nosnippet>432</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE (1 2) (3 4)"</span>;
<a href=#433 id=433 data-nosnippet>433</a> <span class="kw">let </span>result =
<a href=#434 id=434 data-nosnippet>434</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#435 id=435 data-nosnippet>435</a> <span class="macro">assert!</span>(
<a href=#436 id=436 data-nosnippet>436</a> result.is_err() &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"expected: 'a comma'"</span>),
<a href=#437 id=437 data-nosnippet>437</a> <span class="string">"result is: {result:?}"
<a href=#438 id=438 data-nosnippet>438</a> </span>);
<a href=#439 id=439 data-nosnippet>439</a>
<a href=#440 id=440 data-nosnippet>440</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE (,),(3,4)"</span>;
<a href=#441 id=441 data-nosnippet>441</a> <span class="kw">let </span>result =
<a href=#442 id=442 data-nosnippet>442</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#443 id=443 data-nosnippet>443</a> <span class="macro">assert!</span>(
<a href=#444 id=444 data-nosnippet>444</a> result.is_err() &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"Expected: a value, found: ,"</span>),
<a href=#445 id=445 data-nosnippet>445</a> <span class="string">"result is: {result:?}"
<a href=#446 id=446 data-nosnippet>446</a> </span>);
<a href=#447 id=447 data-nosnippet>447</a>
<a href=#448 id=448 data-nosnippet>448</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE (1,2) (3,4)"</span>;
<a href=#449 id=449 data-nosnippet>449</a> <span class="kw">let </span>result =
<a href=#450 id=450 data-nosnippet>450</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#451 id=451 data-nosnippet>451</a> <span class="macro">assert!</span>(
<a href=#452 id=452 data-nosnippet>452</a> result.is_err()
<a href=#453 id=453 data-nosnippet>453</a> &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>)
<a href=#454 id=454 data-nosnippet>454</a> .contains(<span class="string">"expected: 'a comma or end of statement', found: ("</span>),
<a href=#455 id=455 data-nosnippet>455</a> <span class="string">"result is: {result:?}"
<a href=#456 id=456 data-nosnippet>456</a> </span>);
<a href=#457 id=457 data-nosnippet>457</a>
<a href=#458 id=458 data-nosnippet>458</a> <span class="kw">let </span>sql = <span class="string">"TRUNCATE TABLE foo FILE RANGE (1,2),,,,,,,,,(3,4)"</span>;
<a href=#459 id=459 data-nosnippet>459</a> <span class="kw">let </span>result =
<a href=#460 id=460 data-nosnippet>460</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default());
<a href=#461 id=461 data-nosnippet>461</a> <span class="macro">assert!</span>(
<a href=#462 id=462 data-nosnippet>462</a> result.is_err()
<a href=#463 id=463 data-nosnippet>463</a> &amp;&amp; <span class="macro">format!</span>(<span class="string">"{result:?}"</span>).contains(<span class="string">"expected: 'a left parenthesis', found: ,"</span>),
<a href=#464 id=464 data-nosnippet>464</a> <span class="string">"result is: {result:?}"
<a href=#465 id=465 data-nosnippet>465</a> </span>);
<a href=#466 id=466 data-nosnippet>466</a> }
<a href=#467 id=467 data-nosnippet>467</a>}
</code></pre></div></section></main></body></html>
+583
View File
@@ -0,0 +1,583 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/utils.rs`."><title>utils.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>utils.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::collections::HashMap;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>std::sync::Arc;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>chrono::{DateTime, Utc};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>datafusion::config::ConfigOptions;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>datafusion::error::Result <span class="kw">as </span>DfResult;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>datafusion::execution::SessionStateBuilder;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>datafusion::execution::context::SessionState;
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>datafusion::optimizer::simplify_expressions::ExprSimplifier;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span>datafusion_common::tree_node::{TreeNode, TreeNodeVisitor};
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span>datafusion_common::{DFSchema, ScalarValue, TableReference};
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span>datafusion_expr::simplify::SimplifyContext;
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span>datafusion_expr::{AggregateUDF, Expr, HigherOrderUDF, ScalarUDF, TableSource, WindowUDF};
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">use </span>datafusion_sql::planner::{ContextProvider, SqlToRel};
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">use </span>datatypes::arrow::datatypes::DataType;
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">use </span>datatypes::schema::{
<a href=#31 id=31 data-nosnippet>31</a> COLUMN_COMPRESSION_OPT_KEY_ENCODING, COLUMN_COMPRESSION_OPT_KEY_LEVEL,
<a href=#32 id=32 data-nosnippet>32</a> COLUMN_COMPRESSION_OPT_KEY_PAGE_SIZE, COLUMN_COMPRESSION_OPT_KEY_TYPE,
<a href=#33 id=33 data-nosnippet>33</a> COLUMN_FULLTEXT_OPT_KEY_ANALYZER, COLUMN_FULLTEXT_OPT_KEY_BACKEND,
<a href=#34 id=34 data-nosnippet>34</a> COLUMN_FULLTEXT_OPT_KEY_CASE_SENSITIVE, COLUMN_FULLTEXT_OPT_KEY_FALSE_POSITIVE_RATE,
<a href=#35 id=35 data-nosnippet>35</a> COLUMN_FULLTEXT_OPT_KEY_GRANULARITY, COLUMN_SKIPPING_INDEX_OPT_KEY_FALSE_POSITIVE_RATE,
<a href=#36 id=36 data-nosnippet>36</a> COLUMN_SKIPPING_INDEX_OPT_KEY_GRANULARITY, COLUMN_SKIPPING_INDEX_OPT_KEY_TYPE,
<a href=#37 id=37 data-nosnippet>37</a>};
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">use </span>snafu::{ResultExt, ensure};
<a href=#39 id=39 data-nosnippet>39</a><span class="kw">use </span>sqlparser::dialect::Dialect;
<a href=#40 id=40 data-nosnippet>40</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#41 id=41 data-nosnippet>41</a><span class="kw">use </span>sqlparser::parser::Parser;
<a href=#42 id=42 data-nosnippet>42</a><span class="kw">use </span>table::requests::{SEMANTIC_PREFIX, validate_semantic_option, validate_table_option};
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a><span class="kw">use </span><span class="kw">crate</span>::error::{
<a href=#45 id=45 data-nosnippet>45</a> ConvertToLogicalExpressionSnafu, InvalidSqlSnafu, InvalidTableOptionSnafu, ParseSqlValueSnafu,
<a href=#46 id=46 data-nosnippet>46</a> <span class="prelude-ty">Result</span>, SimplificationSnafu, SyntaxSnafu,
<a href=#47 id=47 data-nosnippet>47</a>};
<a href=#48 id=48 data-nosnippet>48</a><span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#49 id=49 data-nosnippet>49</a><span class="kw">use </span><span class="kw">crate</span>::parsers::with_tql_parser::CteContent;
<a href=#50 id=50 data-nosnippet>50</a><span class="kw">use </span><span class="kw">crate</span>::statements::OptionMap;
<a href=#51 id=51 data-nosnippet>51</a><span class="kw">use </span><span class="kw">crate</span>::statements::query::Query;
<a href=#52 id=52 data-nosnippet>52</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#53 id=53 data-nosnippet>53</a><span class="kw">use </span><span class="kw">crate</span>::util::{OptionValue, parse_option_string};
<a href=#54 id=54 data-nosnippet>54</a>
<a href=#55 id=55 data-nosnippet>55</a><span class="doccomment">/// Check if the given SQL query is a TQL statement. Simple tql cte query is also considered as TQL statement.
<a href=#56 id=56 data-nosnippet>56</a></span><span class="kw">pub fn </span>is_tql(dialect: <span class="kw-2">&amp;</span><span class="kw">dyn </span>Dialect, sql: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;bool&gt; {
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">let </span>stmts = ParserContext::create_with_dialect(sql, dialect, ParseOptions::default())<span class="question-mark">?</span>;
<a href=#58 id=58 data-nosnippet>58</a>
<a href=#59 id=59 data-nosnippet>59</a> <span class="macro">ensure!</span>(
<a href=#60 id=60 data-nosnippet>60</a> stmts.len() == <span class="number">1</span>,
<a href=#61 id=61 data-nosnippet>61</a> InvalidSqlSnafu {
<a href=#62 id=62 data-nosnippet>62</a> msg: <span class="macro">format!</span>(<span class="string">"Expect only one statement, found {}"</span>, stmts.len())
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a> );
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">let </span>stmt = <span class="kw-2">&amp;</span>stmts[<span class="number">0</span>];
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">match </span>stmt {
<a href=#67 id=67 data-nosnippet>67</a> Statement::Tql(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(<span class="bool-val">true</span>),
<a href=#68 id=68 data-nosnippet>68</a> Statement::Query(query) =&gt; <span class="prelude-val">Ok</span>(is_simple_tql_cte_query(query)),
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">Ok</span>(<span class="bool-val">false</span>),
<a href=#70 id=70 data-nosnippet>70</a> }
<a href=#71 id=71 data-nosnippet>71</a>}
<a href=#72 id=72 data-nosnippet>72</a>
<a href=#73 id=73 data-nosnippet>73</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>is_simple_tql_cte_query(query: <span class="kw-2">&amp;</span>Query) -&gt; bool {
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#75 id=75 data-nosnippet>75</a>
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw">let </span><span class="prelude-val">Some</span>(hybrid_cte) = <span class="kw-2">&amp;</span>query.hybrid_cte <span class="kw">else </span>{
<a href=#77 id=77 data-nosnippet>77</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#78 id=78 data-nosnippet>78</a> };
<a href=#79 id=79 data-nosnippet>79</a>
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">if </span>!has_only_hybrid_tql_cte(query) {
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#82 id=82 data-nosnippet>82</a> }
<a href=#83 id=83 data-nosnippet>83</a>
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw">let </span><span class="prelude-val">Some</span>(cte) = hybrid_cte.cte_tables.first() <span class="kw">else </span>{
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#86 id=86 data-nosnippet>86</a> };
<a href=#87 id=87 data-nosnippet>87</a> <span class="kw">if </span>hybrid_cte.cte_tables.len() != <span class="number">1 </span>|| !<span class="macro">matches!</span>(cte.content, CteContent::Tql(<span class="kw">_</span>)) {
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#89 id=89 data-nosnippet>89</a> }
<a href=#90 id=90 data-nosnippet>90</a>
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">let </span><span class="prelude-val">Some</span>(reference) = extract_simple_select_star_reference(query) <span class="kw">else </span>{
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#93 id=93 data-nosnippet>93</a> };
<a href=#94 id=94 data-nosnippet>94</a>
<a href=#95 id=95 data-nosnippet>95</a> <span class="kw">let </span>reference = ParserContext::canonicalize_identifier(reference).value;
<a href=#96 id=96 data-nosnippet>96</a> <span class="kw">let </span>cte_name = ParserContext::canonicalize_identifier(cte.name.clone()).value;
<a href=#97 id=97 data-nosnippet>97</a> reference == cte_name
<a href=#98 id=98 data-nosnippet>98</a>}
<a href=#99 id=99 data-nosnippet>99</a>
<a href=#100 id=100 data-nosnippet>100</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>has_tql_cte(query: <span class="kw-2">&amp;</span>Query) -&gt; bool {
<a href=#101 id=101 data-nosnippet>101</a> query.hybrid_cte.as_ref().is_some_and(|with| {
<a href=#102 id=102 data-nosnippet>102</a> with.cte_tables
<a href=#103 id=103 data-nosnippet>103</a> .iter()
<a href=#104 id=104 data-nosnippet>104</a> .any(|cte| <span class="macro">matches!</span>(cte.content, CteContent::Tql(<span class="kw">_</span>)))
<a href=#105 id=105 data-nosnippet>105</a> })
<a href=#106 id=106 data-nosnippet>106</a>}
<a href=#107 id=107 data-nosnippet>107</a>
<a href=#108 id=108 data-nosnippet>108</a><span class="kw">fn </span>has_only_hybrid_tql_cte(query: <span class="kw-2">&amp;</span>Query) -&gt; bool {
<a href=#109 id=109 data-nosnippet>109</a> query
<a href=#110 id=110 data-nosnippet>110</a> .inner
<a href=#111 id=111 data-nosnippet>111</a> .with
<a href=#112 id=112 data-nosnippet>112</a> .as_ref()
<a href=#113 id=113 data-nosnippet>113</a> .is_none_or(|with| with.cte_tables.is_empty())
<a href=#114 id=114 data-nosnippet>114</a>}
<a href=#115 id=115 data-nosnippet>115</a>
<a href=#116 id=116 data-nosnippet>116</a><span class="kw">fn </span>extract_simple_select_star_reference(query: <span class="kw-2">&amp;</span>Query) -&gt; <span class="prelude-ty">Option</span>&lt;sqlparser::ast::Ident&gt; {
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">use </span>sqlparser::ast::{SetExpr, TableFactor};
<a href=#118 id=118 data-nosnippet>118</a>
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">if </span>!is_plain_query_root(<span class="kw-2">&amp;</span>query.inner) {
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#121 id=121 data-nosnippet>121</a> }
<a href=#122 id=122 data-nosnippet>122</a>
<a href=#123 id=123 data-nosnippet>123</a> <span class="kw">let </span>SetExpr::Select(select) = <span class="kw-2">&amp;*</span>query.inner.body <span class="kw">else </span>{
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#125 id=125 data-nosnippet>125</a> };
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">if </span>!is_plain_select(select) || !is_plain_wildcard_projection(select.projection.as_slice()) {
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#128 id=128 data-nosnippet>128</a> }
<a href=#129 id=129 data-nosnippet>129</a>
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">let </span>[table_with_joins] = select.from.as_slice() <span class="kw">else </span>{
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#132 id=132 data-nosnippet>132</a> };
<a href=#133 id=133 data-nosnippet>133</a> <span class="kw">if </span>!table_with_joins.joins.is_empty() {
<a href=#134 id=134 data-nosnippet>134</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#135 id=135 data-nosnippet>135</a> }
<a href=#136 id=136 data-nosnippet>136</a>
<a href=#137 id=137 data-nosnippet>137</a> <span class="kw">let </span>TableFactor::Table { name, .. } = <span class="kw-2">&amp;</span>table_with_joins.relation <span class="kw">else </span>{
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#139 id=139 data-nosnippet>139</a> };
<a href=#140 id=140 data-nosnippet>140</a> <span class="kw">if </span>name.<span class="number">0</span>.len() != <span class="number">1 </span>{
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#142 id=142 data-nosnippet>142</a> }
<a href=#143 id=143 data-nosnippet>143</a>
<a href=#144 id=144 data-nosnippet>144</a> name.<span class="number">0</span>[<span class="number">0</span>].as_ident().cloned()
<a href=#145 id=145 data-nosnippet>145</a>}
<a href=#146 id=146 data-nosnippet>146</a>
<a href=#147 id=147 data-nosnippet>147</a><span class="kw">fn </span>is_plain_query_root(query: <span class="kw-2">&amp;</span>sqlparser::ast::Query) -&gt; bool {
<a href=#148 id=148 data-nosnippet>148</a> query.order_by.is_none()
<a href=#149 id=149 data-nosnippet>149</a> &amp;&amp; query.limit_clause.is_none()
<a href=#150 id=150 data-nosnippet>150</a> &amp;&amp; query.fetch.is_none()
<a href=#151 id=151 data-nosnippet>151</a> &amp;&amp; query.locks.is_empty()
<a href=#152 id=152 data-nosnippet>152</a> &amp;&amp; query.for_clause.is_none()
<a href=#153 id=153 data-nosnippet>153</a> &amp;&amp; query.settings.is_none()
<a href=#154 id=154 data-nosnippet>154</a> &amp;&amp; query.format_clause.is_none()
<a href=#155 id=155 data-nosnippet>155</a> &amp;&amp; query.pipe_operators.is_empty()
<a href=#156 id=156 data-nosnippet>156</a>}
<a href=#157 id=157 data-nosnippet>157</a>
<a href=#158 id=158 data-nosnippet>158</a><span class="kw">fn </span>is_plain_select(select: <span class="kw-2">&amp;</span>sqlparser::ast::Select) -&gt; bool {
<a href=#159 id=159 data-nosnippet>159</a> <span class="kw">use </span>sqlparser::ast::GroupByExpr;
<a href=#160 id=160 data-nosnippet>160</a>
<a href=#161 id=161 data-nosnippet>161</a> select.distinct.is_none()
<a href=#162 id=162 data-nosnippet>162</a> &amp;&amp; select.top.is_none()
<a href=#163 id=163 data-nosnippet>163</a> &amp;&amp; select.exclude.is_none()
<a href=#164 id=164 data-nosnippet>164</a> &amp;&amp; select.into.is_none()
<a href=#165 id=165 data-nosnippet>165</a> &amp;&amp; select.lateral_views.is_empty()
<a href=#166 id=166 data-nosnippet>166</a> &amp;&amp; select.prewhere.is_none()
<a href=#167 id=167 data-nosnippet>167</a> &amp;&amp; select.selection.is_none()
<a href=#168 id=168 data-nosnippet>168</a> &amp;&amp; <span class="macro">matches!</span>(select.group_by, GroupByExpr::Expressions(<span class="kw-2">ref </span>exprs, <span class="kw">_</span>) <span class="kw">if </span>exprs.is_empty())
<a href=#169 id=169 data-nosnippet>169</a> &amp;&amp; select.cluster_by.is_empty()
<a href=#170 id=170 data-nosnippet>170</a> &amp;&amp; select.distribute_by.is_empty()
<a href=#171 id=171 data-nosnippet>171</a> &amp;&amp; select.sort_by.is_empty()
<a href=#172 id=172 data-nosnippet>172</a> &amp;&amp; select.having.is_none()
<a href=#173 id=173 data-nosnippet>173</a> &amp;&amp; select.named_window.is_empty()
<a href=#174 id=174 data-nosnippet>174</a> &amp;&amp; select.qualify.is_none()
<a href=#175 id=175 data-nosnippet>175</a> &amp;&amp; select.value_table_mode.is_none()
<a href=#176 id=176 data-nosnippet>176</a> &amp;&amp; select.connect_by.is_empty()
<a href=#177 id=177 data-nosnippet>177</a>}
<a href=#178 id=178 data-nosnippet>178</a>
<a href=#179 id=179 data-nosnippet>179</a><span class="kw">fn </span>is_plain_wildcard_projection(projection: <span class="kw-2">&amp;</span>[sqlparser::ast::SelectItem]) -&gt; bool {
<a href=#180 id=180 data-nosnippet>180</a> <span class="kw">use </span>sqlparser::ast::SelectItem;
<a href=#181 id=181 data-nosnippet>181</a>
<a href=#182 id=182 data-nosnippet>182</a> <span class="macro">matches!</span>(
<a href=#183 id=183 data-nosnippet>183</a> projection,
<a href=#184 id=184 data-nosnippet>184</a> [SelectItem::Wildcard(options)]
<a href=#185 id=185 data-nosnippet>185</a> <span class="kw">if </span>options.opt_ilike.is_none()
<a href=#186 id=186 data-nosnippet>186</a> &amp;&amp; options.opt_exclude.is_none()
<a href=#187 id=187 data-nosnippet>187</a> &amp;&amp; options.opt_except.is_none()
<a href=#188 id=188 data-nosnippet>188</a> &amp;&amp; options.opt_replace.is_none()
<a href=#189 id=189 data-nosnippet>189</a> &amp;&amp; options.opt_rename.is_none()
<a href=#190 id=190 data-nosnippet>190</a> )
<a href=#191 id=191 data-nosnippet>191</a>}
<a href=#192 id=192 data-nosnippet>192</a>
<a href=#193 id=193 data-nosnippet>193</a><span class="doccomment">/// Convert a parser expression to a scalar value. This function will try the
<a href=#194 id=194 data-nosnippet>194</a>/// best to resolve and reduce constants. Exprs like `1 + 1` or `now()` can be
<a href=#195 id=195 data-nosnippet>195</a>/// handled properly.
<a href=#196 id=196 data-nosnippet>196</a>///
<a href=#197 id=197 data-nosnippet>197</a>/// if `require_now_expr` is true, it will ensure that the expression contains a `now()` function.
<a href=#198 id=198 data-nosnippet>198</a>/// If the expression does not contain `now()`, it will return an error.
<a href=#199 id=199 data-nosnippet>199</a>///
<a href=#200 id=200 data-nosnippet>200</a></span><span class="kw">pub fn </span>parser_expr_to_scalar_value_literal(
<a href=#201 id=201 data-nosnippet>201</a> expr: sqlparser::ast::Expr,
<a href=#202 id=202 data-nosnippet>202</a> require_now_expr: bool,
<a href=#203 id=203 data-nosnippet>203</a>) -&gt; <span class="prelude-ty">Result</span>&lt;ScalarValue&gt; {
<a href=#204 id=204 data-nosnippet>204</a> parser_expr_to_scalar_value_literal_at(expr, require_now_expr, <span class="prelude-val">None</span>)
<a href=#205 id=205 data-nosnippet>205</a>}
<a href=#206 id=206 data-nosnippet>206</a>
<a href=#207 id=207 data-nosnippet>207</a><span class="doccomment">/// Same as [`parser_expr_to_scalar_value_literal`] but uses the provided
<a href=#208 id=208 data-nosnippet>208</a>/// `scheduled_time` for evaluating `now()`. If `scheduled_time` is
<a href=#209 id=209 data-nosnippet>209</a>/// `Some`, `now()` will be simplified to the given timestamp instead of
<a href=#210 id=210 data-nosnippet>210</a>/// the current wall-clock time.
<a href=#211 id=211 data-nosnippet>211</a></span><span class="kw">pub fn </span>parser_expr_to_scalar_value_literal_at(
<a href=#212 id=212 data-nosnippet>212</a> expr: sqlparser::ast::Expr,
<a href=#213 id=213 data-nosnippet>213</a> require_now_expr: bool,
<a href=#214 id=214 data-nosnippet>214</a> scheduled_time: <span class="prelude-ty">Option</span>&lt;DateTime&lt;Utc&gt;&gt;,
<a href=#215 id=215 data-nosnippet>215</a>) -&gt; <span class="prelude-ty">Result</span>&lt;ScalarValue&gt; {
<a href=#216 id=216 data-nosnippet>216</a> <span class="comment">// 1. convert parser expr to logical expr
<a href=#217 id=217 data-nosnippet>217</a> </span><span class="kw">let </span>empty_df_schema = DFSchema::empty();
<a href=#218 id=218 data-nosnippet>218</a> <span class="kw">let </span>logical_expr = SqlToRel::new(<span class="kw-2">&amp;</span>StubContextProvider::default())
<a href=#219 id=219 data-nosnippet>219</a> .sql_to_expr(expr, <span class="kw-2">&amp;</span>empty_df_schema, <span class="kw-2">&amp;mut </span>Default::default())
<a href=#220 id=220 data-nosnippet>220</a> .context(ConvertToLogicalExpressionSnafu)<span class="question-mark">?</span>;
<a href=#221 id=221 data-nosnippet>221</a>
<a href=#222 id=222 data-nosnippet>222</a> <span class="kw">struct </span>FindNow {
<a href=#223 id=223 data-nosnippet>223</a> found: bool,
<a href=#224 id=224 data-nosnippet>224</a> }
<a href=#225 id=225 data-nosnippet>225</a>
<a href=#226 id=226 data-nosnippet>226</a> <span class="kw">impl </span>TreeNodeVisitor&lt;<span class="lifetime">'_</span>&gt; <span class="kw">for </span>FindNow {
<a href=#227 id=227 data-nosnippet>227</a> <span class="kw">type </span>Node = Expr;
<a href=#228 id=228 data-nosnippet>228</a> <span class="kw">fn </span>f_down(
<a href=#229 id=229 data-nosnippet>229</a> <span class="kw-2">&amp;mut </span><span class="self">self</span>,
<a href=#230 id=230 data-nosnippet>230</a> node: <span class="kw-2">&amp;</span><span class="self">Self</span>::Node,
<a href=#231 id=231 data-nosnippet>231</a> ) -&gt; DfResult&lt;datafusion_common::tree_node::TreeNodeRecursion&gt; {
<a href=#232 id=232 data-nosnippet>232</a> <span class="kw">if let </span>Expr::ScalarFunction(func) = node
<a href=#233 id=233 data-nosnippet>233</a> &amp;&amp; func.name().to_lowercase() == <span class="string">"now"
<a href=#234 id=234 data-nosnippet>234</a> </span>{
<a href=#235 id=235 data-nosnippet>235</a> <span class="kw">if </span>!func.args.is_empty() {
<a href=#236 id=236 data-nosnippet>236</a> <span class="kw">return </span><span class="prelude-val">Err</span>(datafusion_common::DataFusionError::Plan(
<a href=#237 id=237 data-nosnippet>237</a> <span class="string">"now() function should not have arguments"</span>.to_string(),
<a href=#238 id=238 data-nosnippet>238</a> ));
<a href=#239 id=239 data-nosnippet>239</a> }
<a href=#240 id=240 data-nosnippet>240</a> <span class="self">self</span>.found = <span class="bool-val">true</span>;
<a href=#241 id=241 data-nosnippet>241</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(datafusion_common::tree_node::TreeNodeRecursion::Stop);
<a href=#242 id=242 data-nosnippet>242</a> }
<a href=#243 id=243 data-nosnippet>243</a> <span class="prelude-val">Ok</span>(datafusion_common::tree_node::TreeNodeRecursion::Continue)
<a href=#244 id=244 data-nosnippet>244</a> }
<a href=#245 id=245 data-nosnippet>245</a> }
<a href=#246 id=246 data-nosnippet>246</a>
<a href=#247 id=247 data-nosnippet>247</a> <span class="kw">if </span>require_now_expr {
<a href=#248 id=248 data-nosnippet>248</a> <span class="kw">let </span>have_now = {
<a href=#249 id=249 data-nosnippet>249</a> <span class="kw">let </span><span class="kw-2">mut </span>visitor = FindNow { found: <span class="bool-val">false </span>};
<a href=#250 id=250 data-nosnippet>250</a> logical_expr.visit(<span class="kw-2">&amp;mut </span>visitor).unwrap();
<a href=#251 id=251 data-nosnippet>251</a> visitor.found
<a href=#252 id=252 data-nosnippet>252</a> };
<a href=#253 id=253 data-nosnippet>253</a> <span class="kw">if </span>!have_now {
<a href=#254 id=254 data-nosnippet>254</a> <span class="kw">return </span>ParseSqlValueSnafu {
<a href=#255 id=255 data-nosnippet>255</a> msg: <span class="macro">format!</span>(
<a href=#256 id=256 data-nosnippet>256</a> <span class="string">"expected now() expression, but not found in {}"</span>,
<a href=#257 id=257 data-nosnippet>257</a> logical_expr
<a href=#258 id=258 data-nosnippet>258</a> ),
<a href=#259 id=259 data-nosnippet>259</a> }
<a href=#260 id=260 data-nosnippet>260</a> .fail();
<a href=#261 id=261 data-nosnippet>261</a> }
<a href=#262 id=262 data-nosnippet>262</a> }
<a href=#263 id=263 data-nosnippet>263</a>
<a href=#264 id=264 data-nosnippet>264</a> <span class="comment">// 2. simplify logical expr — use scheduled time if provided, else wall-clock
<a href=#265 id=265 data-nosnippet>265</a> </span><span class="kw">let </span>info = <span class="kw">match </span>scheduled_time {
<a href=#266 id=266 data-nosnippet>266</a> <span class="prelude-val">Some</span>(dt) =&gt; SimplifyContext::builder()
<a href=#267 id=267 data-nosnippet>267</a> .with_query_execution_start_time(<span class="prelude-val">Some</span>(dt))
<a href=#268 id=268 data-nosnippet>268</a> .build(),
<a href=#269 id=269 data-nosnippet>269</a> <span class="prelude-val">None </span>=&gt; SimplifyContext::builder().with_current_time().build(),
<a href=#270 id=270 data-nosnippet>270</a> };
<a href=#271 id=271 data-nosnippet>271</a> <span class="kw">let </span>simplifier = ExprSimplifier::new(info);
<a href=#272 id=272 data-nosnippet>272</a>
<a href=#273 id=273 data-nosnippet>273</a> <span class="comment">// Coerce the logical expression so simplifier can handle it correctly. This is necessary for const eval with possible type mismatch. i.e.: `now() - now() + '15s'::interval` which is `TimestampNanosecond - TimestampNanosecond + IntervalMonthDayNano`.
<a href=#274 id=274 data-nosnippet>274</a> </span><span class="kw">let </span>logical_expr = simplifier
<a href=#275 id=275 data-nosnippet>275</a> .coerce(logical_expr, <span class="kw-2">&amp;</span>empty_df_schema)
<a href=#276 id=276 data-nosnippet>276</a> .context(SimplificationSnafu)<span class="question-mark">?</span>;
<a href=#277 id=277 data-nosnippet>277</a>
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">let </span>simplified_expr = simplifier
<a href=#279 id=279 data-nosnippet>279</a> .simplify(logical_expr)
<a href=#280 id=280 data-nosnippet>280</a> .context(SimplificationSnafu)<span class="question-mark">?</span>;
<a href=#281 id=281 data-nosnippet>281</a>
<a href=#282 id=282 data-nosnippet>282</a> <span class="kw">if let </span>datafusion::logical_expr::Expr::Literal(lit, <span class="kw">_</span>) = simplified_expr {
<a href=#283 id=283 data-nosnippet>283</a> <span class="prelude-val">Ok</span>(lit)
<a href=#284 id=284 data-nosnippet>284</a> } <span class="kw">else </span>{
<a href=#285 id=285 data-nosnippet>285</a> <span class="comment">// Err(ParseSqlValue)
<a href=#286 id=286 data-nosnippet>286</a> </span>ParseSqlValueSnafu {
<a href=#287 id=287 data-nosnippet>287</a> msg: <span class="macro">format!</span>(<span class="string">"expected literal value, but found {:?}"</span>, simplified_expr),
<a href=#288 id=288 data-nosnippet>288</a> }
<a href=#289 id=289 data-nosnippet>289</a> .fail()
<a href=#290 id=290 data-nosnippet>290</a> }
<a href=#291 id=291 data-nosnippet>291</a>}
<a href=#292 id=292 data-nosnippet>292</a>
<a href=#293 id=293 data-nosnippet>293</a><span class="doccomment">/// Helper struct for [`parser_expr_to_scalar_value`].
<a href=#294 id=294 data-nosnippet>294</a></span><span class="kw">struct </span>StubContextProvider {
<a href=#295 id=295 data-nosnippet>295</a> state: SessionState,
<a href=#296 id=296 data-nosnippet>296</a>}
<a href=#297 id=297 data-nosnippet>297</a>
<a href=#298 id=298 data-nosnippet>298</a><span class="kw">impl </span>Default <span class="kw">for </span>StubContextProvider {
<a href=#299 id=299 data-nosnippet>299</a> <span class="kw">fn </span>default() -&gt; <span class="self">Self </span>{
<a href=#300 id=300 data-nosnippet>300</a> <span class="self">Self </span>{
<a href=#301 id=301 data-nosnippet>301</a> state: SessionStateBuilder::new()
<a href=#302 id=302 data-nosnippet>302</a> .with_config(Default::default())
<a href=#303 id=303 data-nosnippet>303</a> .with_runtime_env(Default::default())
<a href=#304 id=304 data-nosnippet>304</a> .with_default_features()
<a href=#305 id=305 data-nosnippet>305</a> .build(),
<a href=#306 id=306 data-nosnippet>306</a> }
<a href=#307 id=307 data-nosnippet>307</a> }
<a href=#308 id=308 data-nosnippet>308</a>}
<a href=#309 id=309 data-nosnippet>309</a>
<a href=#310 id=310 data-nosnippet>310</a><span class="kw">impl </span>ContextProvider <span class="kw">for </span>StubContextProvider {
<a href=#311 id=311 data-nosnippet>311</a> <span class="kw">fn </span>get_table_source(<span class="kw-2">&amp;</span><span class="self">self</span>, _name: TableReference) -&gt; DfResult&lt;Arc&lt;<span class="kw">dyn </span>TableSource&gt;&gt; {
<a href=#312 id=312 data-nosnippet>312</a> <span class="macro">unimplemented!</span>()
<a href=#313 id=313 data-nosnippet>313</a> }
<a href=#314 id=314 data-nosnippet>314</a>
<a href=#315 id=315 data-nosnippet>315</a> <span class="kw">fn </span>get_function_meta(<span class="kw-2">&amp;</span><span class="self">self</span>, name: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;Arc&lt;ScalarUDF&gt;&gt; {
<a href=#316 id=316 data-nosnippet>316</a> <span class="self">self</span>.state.scalar_functions().get(name).cloned()
<a href=#317 id=317 data-nosnippet>317</a> }
<a href=#318 id=318 data-nosnippet>318</a>
<a href=#319 id=319 data-nosnippet>319</a> <span class="kw">fn </span>get_higher_order_meta(<span class="kw-2">&amp;</span><span class="self">self</span>, name: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;Arc&lt;HigherOrderUDF&gt;&gt; {
<a href=#320 id=320 data-nosnippet>320</a> <span class="self">self</span>.state.higher_order_functions().get(name).cloned()
<a href=#321 id=321 data-nosnippet>321</a> }
<a href=#322 id=322 data-nosnippet>322</a>
<a href=#323 id=323 data-nosnippet>323</a> <span class="kw">fn </span>get_aggregate_meta(<span class="kw-2">&amp;</span><span class="self">self</span>, name: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;Arc&lt;AggregateUDF&gt;&gt; {
<a href=#324 id=324 data-nosnippet>324</a> <span class="self">self</span>.state.aggregate_functions().get(name).cloned()
<a href=#325 id=325 data-nosnippet>325</a> }
<a href=#326 id=326 data-nosnippet>326</a>
<a href=#327 id=327 data-nosnippet>327</a> <span class="kw">fn </span>get_window_meta(<span class="kw-2">&amp;</span><span class="self">self</span>, _name: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;Arc&lt;WindowUDF&gt;&gt; {
<a href=#328 id=328 data-nosnippet>328</a> <span class="macro">unimplemented!</span>()
<a href=#329 id=329 data-nosnippet>329</a> }
<a href=#330 id=330 data-nosnippet>330</a>
<a href=#331 id=331 data-nosnippet>331</a> <span class="kw">fn </span>get_variable_type(<span class="kw-2">&amp;</span><span class="self">self</span>, _variable_names: <span class="kw-2">&amp;</span>[String]) -&gt; <span class="prelude-ty">Option</span>&lt;DataType&gt; {
<a href=#332 id=332 data-nosnippet>332</a> <span class="macro">unimplemented!</span>()
<a href=#333 id=333 data-nosnippet>333</a> }
<a href=#334 id=334 data-nosnippet>334</a>
<a href=#335 id=335 data-nosnippet>335</a> <span class="kw">fn </span>options(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ConfigOptions {
<a href=#336 id=336 data-nosnippet>336</a> <span class="self">self</span>.state.config_options()
<a href=#337 id=337 data-nosnippet>337</a> }
<a href=#338 id=338 data-nosnippet>338</a>
<a href=#339 id=339 data-nosnippet>339</a> <span class="kw">fn </span>udf_names(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;String&gt; {
<a href=#340 id=340 data-nosnippet>340</a> <span class="self">self</span>.state.scalar_functions().keys().cloned().collect()
<a href=#341 id=341 data-nosnippet>341</a> }
<a href=#342 id=342 data-nosnippet>342</a>
<a href=#343 id=343 data-nosnippet>343</a> <span class="kw">fn </span>higher_order_function_names(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;String&gt; {
<a href=#344 id=344 data-nosnippet>344</a> <span class="self">self</span>.state
<a href=#345 id=345 data-nosnippet>345</a> .higher_order_functions()
<a href=#346 id=346 data-nosnippet>346</a> .keys()
<a href=#347 id=347 data-nosnippet>347</a> .cloned()
<a href=#348 id=348 data-nosnippet>348</a> .collect()
<a href=#349 id=349 data-nosnippet>349</a> }
<a href=#350 id=350 data-nosnippet>350</a>
<a href=#351 id=351 data-nosnippet>351</a> <span class="kw">fn </span>udaf_names(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;String&gt; {
<a href=#352 id=352 data-nosnippet>352</a> <span class="self">self</span>.state.aggregate_functions().keys().cloned().collect()
<a href=#353 id=353 data-nosnippet>353</a> }
<a href=#354 id=354 data-nosnippet>354</a>
<a href=#355 id=355 data-nosnippet>355</a> <span class="kw">fn </span>udwf_names(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;String&gt; {
<a href=#356 id=356 data-nosnippet>356</a> <span class="self">self</span>.state.window_functions().keys().cloned().collect()
<a href=#357 id=357 data-nosnippet>357</a> }
<a href=#358 id=358 data-nosnippet>358</a>}
<a href=#359 id=359 data-nosnippet>359</a>
<a href=#360 id=360 data-nosnippet>360</a><span class="kw">pub fn </span>validate_column_fulltext_create_option(key: <span class="kw-2">&amp;</span>str) -&gt; bool {
<a href=#361 id=361 data-nosnippet>361</a> [
<a href=#362 id=362 data-nosnippet>362</a> COLUMN_FULLTEXT_OPT_KEY_ANALYZER,
<a href=#363 id=363 data-nosnippet>363</a> COLUMN_FULLTEXT_OPT_KEY_CASE_SENSITIVE,
<a href=#364 id=364 data-nosnippet>364</a> COLUMN_FULLTEXT_OPT_KEY_BACKEND,
<a href=#365 id=365 data-nosnippet>365</a> COLUMN_FULLTEXT_OPT_KEY_GRANULARITY,
<a href=#366 id=366 data-nosnippet>366</a> COLUMN_FULLTEXT_OPT_KEY_FALSE_POSITIVE_RATE,
<a href=#367 id=367 data-nosnippet>367</a> ]
<a href=#368 id=368 data-nosnippet>368</a> .contains(<span class="kw-2">&amp;</span>key)
<a href=#369 id=369 data-nosnippet>369</a>}
<a href=#370 id=370 data-nosnippet>370</a>
<a href=#371 id=371 data-nosnippet>371</a><span class="kw">pub fn </span>validate_column_skipping_index_create_option(key: <span class="kw-2">&amp;</span>str) -&gt; bool {
<a href=#372 id=372 data-nosnippet>372</a> [
<a href=#373 id=373 data-nosnippet>373</a> COLUMN_SKIPPING_INDEX_OPT_KEY_GRANULARITY,
<a href=#374 id=374 data-nosnippet>374</a> COLUMN_SKIPPING_INDEX_OPT_KEY_TYPE,
<a href=#375 id=375 data-nosnippet>375</a> COLUMN_SKIPPING_INDEX_OPT_KEY_FALSE_POSITIVE_RATE,
<a href=#376 id=376 data-nosnippet>376</a> ]
<a href=#377 id=377 data-nosnippet>377</a> .contains(<span class="kw-2">&amp;</span>key)
<a href=#378 id=378 data-nosnippet>378</a>}
<a href=#379 id=379 data-nosnippet>379</a>
<a href=#380 id=380 data-nosnippet>380</a><span class="kw">pub fn </span>validate_column_compression_create_option(key: <span class="kw-2">&amp;</span>str) -&gt; bool {
<a href=#381 id=381 data-nosnippet>381</a> [
<a href=#382 id=382 data-nosnippet>382</a> COLUMN_COMPRESSION_OPT_KEY_TYPE,
<a href=#383 id=383 data-nosnippet>383</a> COLUMN_COMPRESSION_OPT_KEY_LEVEL,
<a href=#384 id=384 data-nosnippet>384</a> COLUMN_COMPRESSION_OPT_KEY_PAGE_SIZE,
<a href=#385 id=385 data-nosnippet>385</a> COLUMN_COMPRESSION_OPT_KEY_ENCODING,
<a href=#386 id=386 data-nosnippet>386</a> ]
<a href=#387 id=387 data-nosnippet>387</a> .contains(<span class="kw-2">&amp;</span>key)
<a href=#388 id=388 data-nosnippet>388</a>}
<a href=#389 id=389 data-nosnippet>389</a>
<a href=#390 id=390 data-nosnippet>390</a><span class="doccomment">/// Convert an [`IntervalMonthDayNano`] to a [`Duration`].
<a href=#391 id=391 data-nosnippet>391</a></span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#392 id=392 data-nosnippet>392</a></span><span class="kw">pub fn </span>convert_month_day_nano_to_duration(
<a href=#393 id=393 data-nosnippet>393</a> interval: arrow_buffer::IntervalMonthDayNano,
<a href=#394 id=394 data-nosnippet>394</a>) -&gt; <span class="prelude-ty">Result</span>&lt;std::time::Duration&gt; {
<a href=#395 id=395 data-nosnippet>395</a> <span class="kw">let </span>months: i64 = interval.months.into();
<a href=#396 id=396 data-nosnippet>396</a> <span class="kw">let </span>days: i64 = interval.days.into();
<a href=#397 id=397 data-nosnippet>397</a> <span class="kw">let </span>months_in_seconds: i64 = months * <span class="number">60 </span>* <span class="number">60 </span>* <span class="number">24 </span>* <span class="number">3044 </span>/ <span class="number">1000</span>;
<a href=#398 id=398 data-nosnippet>398</a> <span class="kw">let </span>days_in_seconds: i64 = days * <span class="number">60 </span>* <span class="number">60 </span>* <span class="number">24</span>;
<a href=#399 id=399 data-nosnippet>399</a> <span class="kw">let </span>seconds_from_nanos = interval.nanoseconds / <span class="number">1_000_000_000</span>;
<a href=#400 id=400 data-nosnippet>400</a> <span class="kw">let </span>total_seconds = months_in_seconds + days_in_seconds + seconds_from_nanos;
<a href=#401 id=401 data-nosnippet>401</a>
<a href=#402 id=402 data-nosnippet>402</a> <span class="kw">let </span><span class="kw-2">mut </span>nanos_remainder = interval.nanoseconds % <span class="number">1_000_000_000</span>;
<a href=#403 id=403 data-nosnippet>403</a> <span class="kw">let </span><span class="kw-2">mut </span>adjusted_seconds = total_seconds;
<a href=#404 id=404 data-nosnippet>404</a>
<a href=#405 id=405 data-nosnippet>405</a> <span class="kw">if </span>nanos_remainder &lt; <span class="number">0 </span>{
<a href=#406 id=406 data-nosnippet>406</a> nanos_remainder += <span class="number">1_000_000_000</span>;
<a href=#407 id=407 data-nosnippet>407</a> adjusted_seconds -= <span class="number">1</span>;
<a href=#408 id=408 data-nosnippet>408</a> }
<a href=#409 id=409 data-nosnippet>409</a>
<a href=#410 id=410 data-nosnippet>410</a> <span class="macro">snafu::ensure!</span>(
<a href=#411 id=411 data-nosnippet>411</a> adjusted_seconds &gt;= <span class="number">0</span>,
<a href=#412 id=412 data-nosnippet>412</a> <span class="kw">crate</span>::error::InvalidIntervalSnafu {
<a href=#413 id=413 data-nosnippet>413</a> reason: <span class="string">"must be a positive interval"</span>,
<a href=#414 id=414 data-nosnippet>414</a> }
<a href=#415 id=415 data-nosnippet>415</a> );
<a href=#416 id=416 data-nosnippet>416</a>
<a href=#417 id=417 data-nosnippet>417</a> <span class="comment">// Cast safety: `adjusted_seconds` is guaranteed to be non-negative before.
<a href=#418 id=418 data-nosnippet>418</a> </span><span class="kw">let </span>adjusted_seconds = adjusted_seconds <span class="kw">as </span>u64;
<a href=#419 id=419 data-nosnippet>419</a> <span class="comment">// Cast safety: `nanos_remainder` is smaller than 1_000_000_000 which
<a href=#420 id=420 data-nosnippet>420</a> // is checked above.
<a href=#421 id=421 data-nosnippet>421</a> </span><span class="kw">let </span>nanos_remainder = nanos_remainder <span class="kw">as </span>u32;
<a href=#422 id=422 data-nosnippet>422</a>
<a href=#423 id=423 data-nosnippet>423</a> <span class="prelude-val">Ok</span>(std::time::Duration::new(adjusted_seconds, nanos_remainder))
<a href=#424 id=424 data-nosnippet>424</a>}
<a href=#425 id=425 data-nosnippet>425</a>
<a href=#426 id=426 data-nosnippet>426</a><span class="kw">pub fn </span>parse_with_options(parser: <span class="kw-2">&amp;mut </span>Parser) -&gt; <span class="prelude-ty">Result</span>&lt;OptionMap&gt; {
<a href=#427 id=427 data-nosnippet>427</a> <span class="kw">let </span>options = parser
<a href=#428 id=428 data-nosnippet>428</a> .parse_options(Keyword::WITH)
<a href=#429 id=429 data-nosnippet>429</a> .context(SyntaxSnafu)<span class="question-mark">?
<a href=#430 id=430 data-nosnippet>430</a> </span>.into_iter()
<a href=#431 id=431 data-nosnippet>431</a> .map(parse_option_string)
<a href=#432 id=432 data-nosnippet>432</a> .collect::&lt;<span class="prelude-ty">Result</span>&lt;HashMap&lt;String, OptionValue&gt;&gt;&gt;()<span class="question-mark">?</span>;
<a href=#433 id=433 data-nosnippet>433</a> <span class="kw">for </span>(key, value) <span class="kw">in </span><span class="kw-2">&amp;</span>options {
<a href=#434 id=434 data-nosnippet>434</a> <span class="kw">if </span>key.starts_with(SEMANTIC_PREFIX) {
<a href=#435 id=435 data-nosnippet>435</a> <span class="comment">// Semantic keys are whitelisted and value-checked against their domain,
<a href=#436 id=436 data-nosnippet>436</a> // so a user cannot set an unknown key or an out-of-range value.
<a href=#437 id=437 data-nosnippet>437</a> </span><span class="kw">let </span>value = value.as_string().unwrap_or_default();
<a href=#438 id=438 data-nosnippet>438</a> <span class="macro">ensure!</span>(
<a href=#439 id=439 data-nosnippet>439</a> validate_semantic_option(key, value),
<a href=#440 id=440 data-nosnippet>440</a> InvalidTableOptionSnafu { key }
<a href=#441 id=441 data-nosnippet>441</a> );
<a href=#442 id=442 data-nosnippet>442</a> } <span class="kw">else </span>{
<a href=#443 id=443 data-nosnippet>443</a> <span class="macro">ensure!</span>(validate_table_option(key), InvalidTableOptionSnafu { key });
<a href=#444 id=444 data-nosnippet>444</a> }
<a href=#445 id=445 data-nosnippet>445</a> }
<a href=#446 id=446 data-nosnippet>446</a> <span class="prelude-val">Ok</span>(OptionMap::new(options))
<a href=#447 id=447 data-nosnippet>447</a>}
<a href=#448 id=448 data-nosnippet>448</a>
<a href=#449 id=449 data-nosnippet>449</a><span class="attr">#[cfg(test)]
<a href=#450 id=450 data-nosnippet>450</a></span><span class="kw">mod </span>tests {
<a href=#451 id=451 data-nosnippet>451</a> <span class="kw">use </span>chrono::DateTime;
<a href=#452 id=452 data-nosnippet>452</a> <span class="kw">use </span>datafusion::functions::datetime::expr_fn::now;
<a href=#453 id=453 data-nosnippet>453</a> <span class="kw">use </span>datafusion_expr::lit;
<a href=#454 id=454 data-nosnippet>454</a> <span class="kw">use </span>datatypes::arrow::datatypes::TimestampNanosecondType;
<a href=#455 id=455 data-nosnippet>455</a>
<a href=#456 id=456 data-nosnippet>456</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#457 id=457 data-nosnippet>457</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#458 id=458 data-nosnippet>458</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#459 id=459 data-nosnippet>459</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#460 id=460 data-nosnippet>460</a>
<a href=#461 id=461 data-nosnippet>461</a> <span class="attr">#[test]
<a href=#462 id=462 data-nosnippet>462</a> </span><span class="kw">fn </span>test_is_tql() {
<a href=#463 id=463 data-nosnippet>463</a> <span class="kw">let </span>dialect = GreptimeDbDialect {};
<a href=#464 id=464 data-nosnippet>464</a>
<a href=#465 id=465 data-nosnippet>465</a> <span class="macro">assert!</span>(is_tql(<span class="kw-2">&amp;</span>dialect, <span class="string">"TQL EVAL (0, 10, '1s') cpu_usage_total"</span>).unwrap());
<a href=#466 id=466 data-nosnippet>466</a> <span class="macro">assert!</span>(!is_tql(<span class="kw-2">&amp;</span>dialect, <span class="string">"SELECT 1"</span>).unwrap());
<a href=#467 id=467 data-nosnippet>467</a>
<a href=#468 id=468 data-nosnippet>468</a> <span class="kw">let </span>tql_cte = <span class="string">r#"
<a href=#469 id=469 data-nosnippet>469</a>WITH tql_cte(ts, val) AS (
<a href=#470 id=470 data-nosnippet>470</a> TQL EVAL (0, 15, '5s') metric
<a href=#471 id=471 data-nosnippet>471</a>)
<a href=#472 id=472 data-nosnippet>472</a>SELECT * FROM tql_cte
<a href=#473 id=473 data-nosnippet>473</a>"#</span>;
<a href=#474 id=474 data-nosnippet>474</a> <span class="macro">assert!</span>(is_tql(<span class="kw-2">&amp;</span>dialect, tql_cte).unwrap());
<a href=#475 id=475 data-nosnippet>475</a>
<a href=#476 id=476 data-nosnippet>476</a> <span class="kw">let </span>rename_cols = <span class="string">r#"
<a href=#477 id=477 data-nosnippet>477</a>WITH tql (the_timestamp, the_value) AS (
<a href=#478 id=478 data-nosnippet>478</a> TQL EVAL (0, 40, '10s') metric
<a href=#479 id=479 data-nosnippet>479</a>)
<a href=#480 id=480 data-nosnippet>480</a>SELECT * FROM tql
<a href=#481 id=481 data-nosnippet>481</a>"#</span>;
<a href=#482 id=482 data-nosnippet>482</a> <span class="macro">assert!</span>(is_tql(<span class="kw-2">&amp;</span>dialect, rename_cols).unwrap());
<a href=#483 id=483 data-nosnippet>483</a> <span class="kw">let </span>stmts =
<a href=#484 id=484 data-nosnippet>484</a> ParserContext::create_with_dialect(rename_cols, <span class="kw-2">&amp;</span>dialect, ParseOptions::default())
<a href=#485 id=485 data-nosnippet>485</a> .unwrap();
<a href=#486 id=486 data-nosnippet>486</a> <span class="kw">let </span>Statement::Query(q) = <span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] <span class="kw">else </span>{
<a href=#487 id=487 data-nosnippet>487</a> <span class="macro">panic!</span>(<span class="string">"Expected Query statement"</span>);
<a href=#488 id=488 data-nosnippet>488</a> };
<a href=#489 id=489 data-nosnippet>489</a> <span class="kw">let </span>hybrid = q.hybrid_cte.as_ref().expect(<span class="string">"Expected hybrid cte"</span>);
<a href=#490 id=490 data-nosnippet>490</a> <span class="macro">assert_eq!</span>(hybrid.cte_tables.len(), <span class="number">1</span>);
<a href=#491 id=491 data-nosnippet>491</a> <span class="macro">assert_eq!</span>(hybrid.cte_tables[<span class="number">0</span>].columns.len(), <span class="number">2</span>);
<a href=#492 id=492 data-nosnippet>492</a> <span class="macro">assert_eq!</span>(hybrid.cte_tables[<span class="number">0</span>].columns[<span class="number">0</span>].to_string(), <span class="string">"the_timestamp"</span>);
<a href=#493 id=493 data-nosnippet>493</a> <span class="macro">assert_eq!</span>(hybrid.cte_tables[<span class="number">0</span>].columns[<span class="number">1</span>].to_string(), <span class="string">"the_value"</span>);
<a href=#494 id=494 data-nosnippet>494</a>
<a href=#495 id=495 data-nosnippet>495</a> <span class="kw">let </span>sql_cte = <span class="string">r#"
<a href=#496 id=496 data-nosnippet>496</a>WITH cte AS (SELECT 1)
<a href=#497 id=497 data-nosnippet>497</a>SELECT * FROM cte
<a href=#498 id=498 data-nosnippet>498</a>"#</span>;
<a href=#499 id=499 data-nosnippet>499</a> <span class="macro">assert!</span>(!is_tql(<span class="kw-2">&amp;</span>dialect, sql_cte).unwrap());
<a href=#500 id=500 data-nosnippet>500</a>
<a href=#501 id=501 data-nosnippet>501</a> <span class="kw">let </span>extra_sql_cte = <span class="string">r#"
<a href=#502 id=502 data-nosnippet>502</a>WITH sql_cte AS (SELECT 1), tql_cte(ts, val) AS (
<a href=#503 id=503 data-nosnippet>503</a> TQL EVAL (0, 15, '5s') metric
<a href=#504 id=504 data-nosnippet>504</a>)
<a href=#505 id=505 data-nosnippet>505</a>SELECT * FROM tql_cte
<a href=#506 id=506 data-nosnippet>506</a>"#</span>;
<a href=#507 id=507 data-nosnippet>507</a> <span class="macro">assert!</span>(!is_tql(<span class="kw-2">&amp;</span>dialect, extra_sql_cte).unwrap());
<a href=#508 id=508 data-nosnippet>508</a>
<a href=#509 id=509 data-nosnippet>509</a> <span class="kw">let </span>not_select_star = <span class="string">r#"
<a href=#510 id=510 data-nosnippet>510</a>WITH tql_cte(ts, val) AS (
<a href=#511 id=511 data-nosnippet>511</a> TQL EVAL (0, 15, '5s') metric
<a href=#512 id=512 data-nosnippet>512</a>)
<a href=#513 id=513 data-nosnippet>513</a>SELECT ts FROM tql_cte
<a href=#514 id=514 data-nosnippet>514</a>"#</span>;
<a href=#515 id=515 data-nosnippet>515</a> <span class="macro">assert!</span>(!is_tql(<span class="kw-2">&amp;</span>dialect, not_select_star).unwrap());
<a href=#516 id=516 data-nosnippet>516</a>
<a href=#517 id=517 data-nosnippet>517</a> <span class="kw">let </span>with_filter = <span class="string">r#"
<a href=#518 id=518 data-nosnippet>518</a>WITH tql_cte(ts, val) AS (
<a href=#519 id=519 data-nosnippet>519</a> TQL EVAL (0, 15, '5s') metric
<a href=#520 id=520 data-nosnippet>520</a>)
<a href=#521 id=521 data-nosnippet>521</a>SELECT * FROM tql_cte WHERE ts &gt; 0
<a href=#522 id=522 data-nosnippet>522</a>"#</span>;
<a href=#523 id=523 data-nosnippet>523</a> <span class="macro">assert!</span>(!is_tql(<span class="kw-2">&amp;</span>dialect, with_filter).unwrap());
<a href=#524 id=524 data-nosnippet>524</a> }
<a href=#525 id=525 data-nosnippet>525</a>
<a href=#526 id=526 data-nosnippet>526</a> <span class="doccomment">/// Keep this test to make sure we are using datafusion's `ExprSimplifier` correctly.
<a href=#527 id=527 data-nosnippet>527</a> </span><span class="attr">#[test]
<a href=#528 id=528 data-nosnippet>528</a> </span><span class="kw">fn </span>test_simplifier() {
<a href=#529 id=529 data-nosnippet>529</a> <span class="kw">let </span>now_time = DateTime::from_timestamp(<span class="number">61</span>, <span class="number">0</span>).unwrap();
<a href=#530 id=530 data-nosnippet>530</a> <span class="kw">let </span>lit_now = lit(ScalarValue::new_timestamp::&lt;TimestampNanosecondType&gt;(
<a href=#531 id=531 data-nosnippet>531</a> now_time.timestamp_nanos_opt(),
<a href=#532 id=532 data-nosnippet>532</a> <span class="prelude-val">None</span>,
<a href=#533 id=533 data-nosnippet>533</a> ));
<a href=#534 id=534 data-nosnippet>534</a> <span class="kw">let </span>testcases = <span class="macro">vec!</span>[
<a href=#535 id=535 data-nosnippet>535</a> (now(), lit_now),
<a href=#536 id=536 data-nosnippet>536</a> (now() - now(), lit(ScalarValue::DurationNanosecond(<span class="prelude-val">Some</span>(<span class="number">0</span>)))),
<a href=#537 id=537 data-nosnippet>537</a> (
<a href=#538 id=538 data-nosnippet>538</a> now() + lit(ScalarValue::new_interval_dt(<span class="number">0</span>, <span class="number">1500</span>)),
<a href=#539 id=539 data-nosnippet>539</a> lit(ScalarValue::new_timestamp::&lt;TimestampNanosecondType&gt;(
<a href=#540 id=540 data-nosnippet>540</a> <span class="prelude-val">Some</span>(<span class="number">62500000000</span>),
<a href=#541 id=541 data-nosnippet>541</a> <span class="prelude-val">None</span>,
<a href=#542 id=542 data-nosnippet>542</a> )),
<a href=#543 id=543 data-nosnippet>543</a> ),
<a href=#544 id=544 data-nosnippet>544</a> (
<a href=#545 id=545 data-nosnippet>545</a> now() - (now() + lit(ScalarValue::new_interval_dt(<span class="number">0</span>, <span class="number">1500</span>))),
<a href=#546 id=546 data-nosnippet>546</a> lit(ScalarValue::DurationNanosecond(<span class="prelude-val">Some</span>(-<span class="number">1500000000</span>))),
<a href=#547 id=547 data-nosnippet>547</a> ),
<a href=#548 id=548 data-nosnippet>548</a> <span class="comment">// this one failed if type is not coerced
<a href=#549 id=549 data-nosnippet>549</a> </span>(
<a href=#550 id=550 data-nosnippet>550</a> now() - now() + lit(ScalarValue::new_interval_dt(<span class="number">0</span>, <span class="number">1500</span>)),
<a href=#551 id=551 data-nosnippet>551</a> lit(ScalarValue::new_interval_mdn(<span class="number">0</span>, <span class="number">0</span>, <span class="number">1500000000</span>)),
<a href=#552 id=552 data-nosnippet>552</a> ),
<a href=#553 id=553 data-nosnippet>553</a> (
<a href=#554 id=554 data-nosnippet>554</a> lit(ScalarValue::new_interval_mdn(
<a href=#555 id=555 data-nosnippet>555</a> <span class="number">0</span>,
<a href=#556 id=556 data-nosnippet>556</a> <span class="number">0</span>,
<a href=#557 id=557 data-nosnippet>557</a> <span class="number">61 </span>* <span class="number">86400 </span>* <span class="number">1_000_000_000</span>,
<a href=#558 id=558 data-nosnippet>558</a> )),
<a href=#559 id=559 data-nosnippet>559</a> lit(ScalarValue::new_interval_mdn(
<a href=#560 id=560 data-nosnippet>560</a> <span class="number">0</span>,
<a href=#561 id=561 data-nosnippet>561</a> <span class="number">0</span>,
<a href=#562 id=562 data-nosnippet>562</a> <span class="number">61 </span>* <span class="number">86400 </span>* <span class="number">1_000_000_000</span>,
<a href=#563 id=563 data-nosnippet>563</a> )),
<a href=#564 id=564 data-nosnippet>564</a> ),
<a href=#565 id=565 data-nosnippet>565</a> ];
<a href=#566 id=566 data-nosnippet>566</a>
<a href=#567 id=567 data-nosnippet>567</a> <span class="kw">let </span>info = SimplifyContext::builder()
<a href=#568 id=568 data-nosnippet>568</a> .with_query_execution_start_time(<span class="prelude-val">Some</span>(now_time))
<a href=#569 id=569 data-nosnippet>569</a> .build();
<a href=#570 id=570 data-nosnippet>570</a> <span class="kw">let </span>simplifier = ExprSimplifier::new(info);
<a href=#571 id=571 data-nosnippet>571</a> <span class="kw">for </span>(expr, expected) <span class="kw">in </span>testcases {
<a href=#572 id=572 data-nosnippet>572</a> <span class="kw">let </span>expr_name = expr.schema_name().to_string();
<a href=#573 id=573 data-nosnippet>573</a> <span class="kw">let </span>expr = simplifier.coerce(expr, <span class="kw-2">&amp;</span>DFSchema::empty()).unwrap();
<a href=#574 id=574 data-nosnippet>574</a>
<a href=#575 id=575 data-nosnippet>575</a> <span class="kw">let </span>simplified_expr = simplifier.simplify(expr).unwrap();
<a href=#576 id=576 data-nosnippet>576</a> <span class="macro">assert_eq!</span>(
<a href=#577 id=577 data-nosnippet>577</a> simplified_expr, expected,
<a href=#578 id=578 data-nosnippet>578</a> <span class="string">"Failed to simplify expression: {expr_name}"
<a href=#579 id=579 data-nosnippet>579</a> </span>);
<a href=#580 id=580 data-nosnippet>580</a> }
<a href=#581 id=581 data-nosnippet>581</a> }
<a href=#582 id=582 data-nosnippet>582</a>}
</code></pre></div></section></main></body></html>
+379
View File
@@ -0,0 +1,379 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/parsers/with_tql_parser.rs`."><title>with_tql_parser.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/parsers/</div>with_tql_parser.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>snafu::ResultExt;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser::ast::helpers::attached_token::AttachedToken;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>sqlparser::ast::{
<a href=#21 id=21 data-nosnippet>21</a> Cte, Ident, ObjectName, Query <span class="kw">as </span>SpQuery, TableAlias, TableAliasColumnDef, With,
<a href=#22 id=22 data-nosnippet>22</a>};
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>sqlparser::keywords::Keyword;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span>sqlparser::parser::IsOptional;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span>sqlparser::tokenizer::Token;
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#27 id=27 data-nosnippet>27</a>
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="self">self</span>, <span class="prelude-ty">Result</span>};
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">use </span><span class="kw">crate</span>::parser::ParserContext;
<a href=#31 id=31 data-nosnippet>31</a><span class="kw">use </span><span class="kw">crate</span>::parsers::tql_parser;
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">use </span><span class="kw">crate</span>::statements::query::Query;
<a href=#33 id=33 data-nosnippet>33</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#34 id=34 data-nosnippet>34</a><span class="kw">use </span><span class="kw">crate</span>::statements::tql::Tql;
<a href=#35 id=35 data-nosnippet>35</a><span class="kw">use </span><span class="kw">crate</span>::util::location_to_index;
<a href=#36 id=36 data-nosnippet>36</a>
<a href=#37 id=37 data-nosnippet>37</a><span class="doccomment">/// Content of a CTE - either SQL or TQL
<a href=#38 id=38 data-nosnippet>38</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#39 id=39 data-nosnippet>39</a></span><span class="kw">pub enum </span>CteContent {
<a href=#40 id=40 data-nosnippet>40</a> Sql(Box&lt;SpQuery&gt;),
<a href=#41 id=41 data-nosnippet>41</a> Tql(Tql),
<a href=#42 id=42 data-nosnippet>42</a>}
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a><span class="doccomment">/// A hybrid CTE that can contain either SQL or TQL
<a href=#45 id=45 data-nosnippet>45</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#46 id=46 data-nosnippet>46</a></span><span class="kw">pub struct </span>HybridCte {
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">pub </span>name: Ident,
<a href=#48 id=48 data-nosnippet>48</a> <span class="doccomment">/// Column aliases for the CTE table. Empty if not specified.
<a href=#49 id=49 data-nosnippet>49</a> </span><span class="kw">pub </span>columns: Vec&lt;ObjectName&gt;,
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">pub </span>content: CteContent,
<a href=#51 id=51 data-nosnippet>51</a>}
<a href=#52 id=52 data-nosnippet>52</a>
<a href=#53 id=53 data-nosnippet>53</a><span class="doccomment">/// Extended WITH clause that supports hybrid SQL/TQL CTEs
<a href=#54 id=54 data-nosnippet>54</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#55 id=55 data-nosnippet>55</a></span><span class="kw">pub struct </span>HybridCteWith {
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">pub </span>recursive: bool,
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">pub </span>cte_tables: Vec&lt;HybridCte&gt;,
<a href=#58 id=58 data-nosnippet>58</a>}
<a href=#59 id=59 data-nosnippet>59</a>
<a href=#60 id=60 data-nosnippet>60</a><span class="kw">impl </span>fmt::Display <span class="kw">for </span>HybridCteWith {
<a href=#61 id=61 data-nosnippet>61</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#62 id=62 data-nosnippet>62</a> <span class="macro">write!</span>(f, <span class="string">"WITH "</span>)<span class="question-mark">?</span>;
<a href=#63 id=63 data-nosnippet>63</a>
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">if </span><span class="self">self</span>.recursive {
<a href=#65 id=65 data-nosnippet>65</a> <span class="macro">write!</span>(f, <span class="string">"RECURSIVE "</span>)<span class="question-mark">?</span>;
<a href=#66 id=66 data-nosnippet>66</a> }
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a> <span class="kw">for </span>(i, cte) <span class="kw">in </span><span class="self">self</span>.cte_tables.iter().enumerate() {
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">if </span>i &gt; <span class="number">0 </span>{
<a href=#70 id=70 data-nosnippet>70</a> <span class="macro">write!</span>(f, <span class="string">", "</span>)<span class="question-mark">?</span>;
<a href=#71 id=71 data-nosnippet>71</a> }
<a href=#72 id=72 data-nosnippet>72</a> <span class="macro">write!</span>(f, <span class="string">"{}"</span>, cte.name)<span class="question-mark">?</span>;
<a href=#73 id=73 data-nosnippet>73</a>
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">if </span>!cte.columns.is_empty() {
<a href=#75 id=75 data-nosnippet>75</a> <span class="macro">write!</span>(f, <span class="string">" ("</span>)<span class="question-mark">?</span>;
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw">for </span>(j, col) <span class="kw">in </span>cte.columns.iter().enumerate() {
<a href=#77 id=77 data-nosnippet>77</a> <span class="kw">if </span>j &gt; <span class="number">0 </span>{
<a href=#78 id=78 data-nosnippet>78</a> <span class="macro">write!</span>(f, <span class="string">", "</span>)<span class="question-mark">?</span>;
<a href=#79 id=79 data-nosnippet>79</a> }
<a href=#80 id=80 data-nosnippet>80</a> <span class="macro">write!</span>(f, <span class="string">"{}"</span>, col)<span class="question-mark">?</span>;
<a href=#81 id=81 data-nosnippet>81</a> }
<a href=#82 id=82 data-nosnippet>82</a> <span class="macro">write!</span>(f, <span class="string">")"</span>)<span class="question-mark">?</span>;
<a href=#83 id=83 data-nosnippet>83</a> }
<a href=#84 id=84 data-nosnippet>84</a>
<a href=#85 id=85 data-nosnippet>85</a> <span class="macro">write!</span>(f, <span class="string">" AS ("</span>)<span class="question-mark">?</span>;
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">match </span><span class="kw-2">&amp;</span>cte.content {
<a href=#87 id=87 data-nosnippet>87</a> CteContent::Sql(query) =&gt; <span class="macro">write!</span>(f, <span class="string">"{}"</span>, query)<span class="question-mark">?</span>,
<a href=#88 id=88 data-nosnippet>88</a> CteContent::Tql(tql) =&gt; <span class="macro">write!</span>(f, <span class="string">"{}"</span>, tql)<span class="question-mark">?</span>,
<a href=#89 id=89 data-nosnippet>89</a> }
<a href=#90 id=90 data-nosnippet>90</a> <span class="macro">write!</span>(f, <span class="string">")"</span>)<span class="question-mark">?</span>;
<a href=#91 id=91 data-nosnippet>91</a> }
<a href=#92 id=92 data-nosnippet>92</a> <span class="prelude-val">Ok</span>(())
<a href=#93 id=93 data-nosnippet>93</a> }
<a href=#94 id=94 data-nosnippet>94</a>}
<a href=#95 id=95 data-nosnippet>95</a>
<a href=#96 id=96 data-nosnippet>96</a><span class="doccomment">/// Parser implementation for hybrid WITH clauses containing TQL
<a href=#97 id=97 data-nosnippet>97</a></span><span class="kw">impl </span>ParserContext&lt;<span class="lifetime">'_</span>&gt; {
<a href=#98 id=98 data-nosnippet>98</a> <span class="doccomment">/// Parse a WITH clause that may contain TQL CTEs or SQL CTEs.
<a href=#99 id=99 data-nosnippet>99</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_with_tql(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#100 id=100 data-nosnippet>100</a> <span class="self">self</span>.parse_with_tql_with_now(<span class="bool-val">false</span>)
<a href=#101 id=101 data-nosnippet>101</a> }
<a href=#102 id=102 data-nosnippet>102</a>
<a href=#103 id=103 data-nosnippet>103</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>parse_with_tql_with_now(<span class="kw-2">&amp;mut </span><span class="self">self</span>, require_now_expr: bool) -&gt; <span class="prelude-ty">Result</span>&lt;Statement&gt; {
<a href=#104 id=104 data-nosnippet>104</a> <span class="comment">// Consume the WITH token
<a href=#105 id=105 data-nosnippet>105</a> </span><span class="self">self</span>.parser
<a href=#106 id=106 data-nosnippet>106</a> .expect_keyword(Keyword::WITH)
<a href=#107 id=107 data-nosnippet>107</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#108 id=108 data-nosnippet>108</a>
<a href=#109 id=109 data-nosnippet>109</a> <span class="comment">// Check for RECURSIVE keyword
<a href=#110 id=110 data-nosnippet>110</a> </span><span class="kw">let </span>recursive = <span class="self">self</span>.parser.parse_keyword(Keyword::RECURSIVE);
<a href=#111 id=111 data-nosnippet>111</a>
<a href=#112 id=112 data-nosnippet>112</a> <span class="comment">// Parse the CTE list
<a href=#113 id=113 data-nosnippet>113</a> </span><span class="kw">let </span><span class="kw-2">mut </span>tql_cte_tables = Vec::new();
<a href=#114 id=114 data-nosnippet>114</a> <span class="kw">let </span><span class="kw-2">mut </span>sql_cte_tables = Vec::new();
<a href=#115 id=115 data-nosnippet>115</a>
<a href=#116 id=116 data-nosnippet>116</a> <span class="kw">loop </span>{
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">let </span>cte = <span class="self">self</span>.parse_hybrid_cte(require_now_expr)<span class="question-mark">?</span>;
<a href=#118 id=118 data-nosnippet>118</a> <span class="kw">match </span>cte.content {
<a href=#119 id=119 data-nosnippet>119</a> CteContent::Sql(body) =&gt; sql_cte_tables.push(Cte {
<a href=#120 id=120 data-nosnippet>120</a> alias: TableAlias {
<a href=#121 id=121 data-nosnippet>121</a> explicit: <span class="bool-val">false</span>,
<a href=#122 id=122 data-nosnippet>122</a> name: cte.name,
<a href=#123 id=123 data-nosnippet>123</a> columns: cte
<a href=#124 id=124 data-nosnippet>124</a> .columns
<a href=#125 id=125 data-nosnippet>125</a> .into_iter()
<a href=#126 id=126 data-nosnippet>126</a> .flat_map(|col| col.<span class="number">0</span>[<span class="number">0</span>].as_ident().cloned())
<a href=#127 id=127 data-nosnippet>127</a> .map(|name| TableAliasColumnDef {
<a href=#128 id=128 data-nosnippet>128</a> name,
<a href=#129 id=129 data-nosnippet>129</a> data_type: <span class="prelude-val">None</span>,
<a href=#130 id=130 data-nosnippet>130</a> })
<a href=#131 id=131 data-nosnippet>131</a> .collect(),
<a href=#132 id=132 data-nosnippet>132</a> at: <span class="prelude-val">None</span>,
<a href=#133 id=133 data-nosnippet>133</a> },
<a href=#134 id=134 data-nosnippet>134</a> query: body,
<a href=#135 id=135 data-nosnippet>135</a> from: <span class="prelude-val">None</span>,
<a href=#136 id=136 data-nosnippet>136</a> materialized: <span class="prelude-val">None</span>,
<a href=#137 id=137 data-nosnippet>137</a> closing_paren_token: AttachedToken::empty(),
<a href=#138 id=138 data-nosnippet>138</a> }),
<a href=#139 id=139 data-nosnippet>139</a> CteContent::Tql(<span class="kw">_</span>) =&gt; tql_cte_tables.push(cte),
<a href=#140 id=140 data-nosnippet>140</a> }
<a href=#141 id=141 data-nosnippet>141</a>
<a href=#142 id=142 data-nosnippet>142</a> <span class="kw">if </span>!<span class="self">self</span>.parser.consume_token(<span class="kw-2">&amp;</span>Token::Comma) {
<a href=#143 id=143 data-nosnippet>143</a> <span class="kw">break</span>;
<a href=#144 id=144 data-nosnippet>144</a> }
<a href=#145 id=145 data-nosnippet>145</a> }
<a href=#146 id=146 data-nosnippet>146</a>
<a href=#147 id=147 data-nosnippet>147</a> <span class="comment">// Parse the main query
<a href=#148 id=148 data-nosnippet>148</a> </span><span class="kw">let </span>main_query = <span class="self">self</span>.parser.parse_query().context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#149 id=149 data-nosnippet>149</a>
<a href=#150 id=150 data-nosnippet>150</a> <span class="comment">// Create a Query statement with hybrid CTE metadata
<a href=#151 id=151 data-nosnippet>151</a> </span><span class="kw">let </span><span class="kw-2">mut </span>query = Query::try_from(<span class="kw-2">*</span>main_query)<span class="question-mark">?</span>;
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">if </span>!tql_cte_tables.is_empty() {
<a href=#153 id=153 data-nosnippet>153</a> query.hybrid_cte = <span class="prelude-val">Some</span>(HybridCteWith {
<a href=#154 id=154 data-nosnippet>154</a> recursive,
<a href=#155 id=155 data-nosnippet>155</a> cte_tables: tql_cte_tables,
<a href=#156 id=156 data-nosnippet>156</a> });
<a href=#157 id=157 data-nosnippet>157</a> }
<a href=#158 id=158 data-nosnippet>158</a> query.inner.with = <span class="prelude-val">Some</span>(With {
<a href=#159 id=159 data-nosnippet>159</a> recursive,
<a href=#160 id=160 data-nosnippet>160</a> cte_tables: sql_cte_tables,
<a href=#161 id=161 data-nosnippet>161</a> with_token: AttachedToken::empty(),
<a href=#162 id=162 data-nosnippet>162</a> });
<a href=#163 id=163 data-nosnippet>163</a>
<a href=#164 id=164 data-nosnippet>164</a> <span class="prelude-val">Ok</span>(Statement::Query(Box::new(query)))
<a href=#165 id=165 data-nosnippet>165</a> }
<a href=#166 id=166 data-nosnippet>166</a>
<a href=#167 id=167 data-nosnippet>167</a> <span class="doccomment">/// Parse a single CTE that can be either SQL or TQL
<a href=#168 id=168 data-nosnippet>168</a> </span><span class="kw">fn </span>parse_hybrid_cte(<span class="kw-2">&amp;mut </span><span class="self">self</span>, require_now_expr: bool) -&gt; <span class="prelude-ty">Result</span>&lt;HybridCte&gt; {
<a href=#169 id=169 data-nosnippet>169</a> <span class="comment">// Parse CTE name
<a href=#170 id=170 data-nosnippet>170</a> </span><span class="kw">let </span>name = <span class="self">self</span>.parser.parse_identifier().context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">let </span>name = <span class="self">Self</span>::canonicalize_identifier(name);
<a href=#172 id=172 data-nosnippet>172</a>
<a href=#173 id=173 data-nosnippet>173</a> <span class="comment">// Parse optional column list
<a href=#174 id=174 data-nosnippet>174</a> </span><span class="kw">let </span>columns = <span class="self">self
<a href=#175 id=175 data-nosnippet>175</a> </span>.parser
<a href=#176 id=176 data-nosnippet>176</a> .parse_parenthesized_qualified_column_list(IsOptional::Optional, <span class="bool-val">true</span>)
<a href=#177 id=177 data-nosnippet>177</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#178 id=178 data-nosnippet>178</a>
<a href=#179 id=179 data-nosnippet>179</a> <span class="comment">// Expect AS keyword
<a href=#180 id=180 data-nosnippet>180</a> </span><span class="self">self</span>.parser
<a href=#181 id=181 data-nosnippet>181</a> .expect_keyword(Keyword::AS)
<a href=#182 id=182 data-nosnippet>182</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#183 id=183 data-nosnippet>183</a>
<a href=#184 id=184 data-nosnippet>184</a> <span class="comment">// Parse the CTE content
<a href=#185 id=185 data-nosnippet>185</a> </span><span class="self">self</span>.parser
<a href=#186 id=186 data-nosnippet>186</a> .expect_token(<span class="kw-2">&amp;</span>Token::LParen)
<a href=#187 id=187 data-nosnippet>187</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#188 id=188 data-nosnippet>188</a>
<a href=#189 id=189 data-nosnippet>189</a> <span class="kw">let </span>content = <span class="self">self</span>.parse_cte_content(require_now_expr)<span class="question-mark">?</span>;
<a href=#190 id=190 data-nosnippet>190</a>
<a href=#191 id=191 data-nosnippet>191</a> <span class="self">self</span>.parser
<a href=#192 id=192 data-nosnippet>192</a> .expect_token(<span class="kw-2">&amp;</span>Token::RParen)
<a href=#193 id=193 data-nosnippet>193</a> .context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#194 id=194 data-nosnippet>194</a>
<a href=#195 id=195 data-nosnippet>195</a> <span class="prelude-val">Ok</span>(HybridCte {
<a href=#196 id=196 data-nosnippet>196</a> name,
<a href=#197 id=197 data-nosnippet>197</a> columns,
<a href=#198 id=198 data-nosnippet>198</a> content,
<a href=#199 id=199 data-nosnippet>199</a> })
<a href=#200 id=200 data-nosnippet>200</a> }
<a href=#201 id=201 data-nosnippet>201</a>
<a href=#202 id=202 data-nosnippet>202</a> <span class="doccomment">/// Determine if CTE contains TQL or SQL and parse accordingly
<a href=#203 id=203 data-nosnippet>203</a> </span><span class="kw">fn </span>parse_cte_content(<span class="kw-2">&amp;mut </span><span class="self">self</span>, require_now_expr: bool) -&gt; <span class="prelude-ty">Result</span>&lt;CteContent&gt; {
<a href=#204 id=204 data-nosnippet>204</a> <span class="comment">// Check if the next token is TQL
<a href=#205 id=205 data-nosnippet>205</a> </span><span class="kw">if let </span>Token::Word(w) = <span class="kw-2">&amp;</span><span class="self">self</span>.parser.peek_token().token
<a href=#206 id=206 data-nosnippet>206</a> &amp;&amp; w.keyword == Keyword::NoKeyword
<a href=#207 id=207 data-nosnippet>207</a> &amp;&amp; w.quote_style.is_none()
<a href=#208 id=208 data-nosnippet>208</a> &amp;&amp; w.value.to_uppercase() == tql_parser::TQL
<a href=#209 id=209 data-nosnippet>209</a> {
<a href=#210 id=210 data-nosnippet>210</a> <span class="kw">let </span>tql = <span class="self">self</span>.parse_tql_content_in_cte(require_now_expr)<span class="question-mark">?</span>;
<a href=#211 id=211 data-nosnippet>211</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(CteContent::Tql(tql));
<a href=#212 id=212 data-nosnippet>212</a> }
<a href=#213 id=213 data-nosnippet>213</a>
<a href=#214 id=214 data-nosnippet>214</a> <span class="comment">// Parse as SQL query
<a href=#215 id=215 data-nosnippet>215</a> </span><span class="kw">let </span>sql_query = <span class="self">self</span>.parser.parse_query().context(error::SyntaxSnafu)<span class="question-mark">?</span>;
<a href=#216 id=216 data-nosnippet>216</a> <span class="prelude-val">Ok</span>(CteContent::Sql(sql_query))
<a href=#217 id=217 data-nosnippet>217</a> }
<a href=#218 id=218 data-nosnippet>218</a>
<a href=#219 id=219 data-nosnippet>219</a> <span class="doccomment">/// Parse TQL content within a CTE by extracting the raw query string.
<a href=#220 id=220 data-nosnippet>220</a> ///
<a href=#221 id=221 data-nosnippet>221</a> /// This method consumes all tokens that belong to the TQL statement and
<a href=#222 id=222 data-nosnippet>222</a> /// stops right **before** the closing `)` of the CTE so that the caller
<a href=#223 id=223 data-nosnippet>223</a> /// can handle it normally.
<a href=#224 id=224 data-nosnippet>224</a> ///
<a href=#225 id=225 data-nosnippet>225</a> /// Only `TQL EVAL` is supported inside CTEs.
<a href=#226 id=226 data-nosnippet>226</a> </span><span class="kw">fn </span>parse_tql_content_in_cte(<span class="kw-2">&amp;mut </span><span class="self">self</span>, require_now_expr: bool) -&gt; <span class="prelude-ty">Result</span>&lt;Tql&gt; {
<a href=#227 id=227 data-nosnippet>227</a> <span class="comment">// Consume and get the position of the TQL keyword
<a href=#228 id=228 data-nosnippet>228</a> </span><span class="kw">let </span>tql_token = <span class="self">self</span>.parser.next_token();
<a href=#229 id=229 data-nosnippet>229</a> <span class="kw">if </span>tql_token.token == Token::EOF {
<a href=#230 id=230 data-nosnippet>230</a> <span class="kw">return </span><span class="prelude-val">Err</span>(error::InvalidSqlSnafu {
<a href=#231 id=231 data-nosnippet>231</a> msg: <span class="string">"Unexpected end of input while parsing TQL inside CTE"</span>.to_string(),
<a href=#232 id=232 data-nosnippet>232</a> }
<a href=#233 id=233 data-nosnippet>233</a> .build());
<a href=#234 id=234 data-nosnippet>234</a> }
<a href=#235 id=235 data-nosnippet>235</a>
<a href=#236 id=236 data-nosnippet>236</a> <span class="kw">let </span>start_location = tql_token.span.start;
<a href=#237 id=237 data-nosnippet>237</a>
<a href=#238 id=238 data-nosnippet>238</a> <span class="comment">// Track parentheses depth to find the end of the CTE
<a href=#239 id=239 data-nosnippet>239</a> </span><span class="kw">let </span><span class="kw-2">mut </span>paren_depth = <span class="number">0usize</span>;
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">let </span>end_location;
<a href=#241 id=241 data-nosnippet>241</a>
<a href=#242 id=242 data-nosnippet>242</a> <span class="kw">loop </span>{
<a href=#243 id=243 data-nosnippet>243</a> <span class="kw">let </span>token_with_span = <span class="self">self</span>.parser.peek_token();
<a href=#244 id=244 data-nosnippet>244</a>
<a href=#245 id=245 data-nosnippet>245</a> <span class="comment">// Guard against unexpected EOF
<a href=#246 id=246 data-nosnippet>246</a> </span><span class="kw">if </span>token_with_span.token == Token::EOF {
<a href=#247 id=247 data-nosnippet>247</a> <span class="kw">return </span><span class="prelude-val">Err</span>(error::InvalidSqlSnafu {
<a href=#248 id=248 data-nosnippet>248</a> msg: <span class="string">"Unexpected end of input while parsing TQL inside CTE"</span>.to_string(),
<a href=#249 id=249 data-nosnippet>249</a> }
<a href=#250 id=250 data-nosnippet>250</a> .build());
<a href=#251 id=251 data-nosnippet>251</a> }
<a href=#252 id=252 data-nosnippet>252</a>
<a href=#253 id=253 data-nosnippet>253</a> <span class="comment">// Stop **before** the closing parenthesis that ends the CTE
<a href=#254 id=254 data-nosnippet>254</a> </span><span class="kw">if </span>token_with_span.token == Token::RParen &amp;&amp; paren_depth == <span class="number">0 </span>{
<a href=#255 id=255 data-nosnippet>255</a> end_location = token_with_span.span.start;
<a href=#256 id=256 data-nosnippet>256</a> <span class="kw">break</span>;
<a href=#257 id=257 data-nosnippet>257</a> }
<a href=#258 id=258 data-nosnippet>258</a>
<a href=#259 id=259 data-nosnippet>259</a> <span class="comment">// Consume the token and track parentheses depth
<a href=#260 id=260 data-nosnippet>260</a> </span><span class="kw">let </span>consumed = <span class="self">self</span>.parser.next_token();
<a href=#261 id=261 data-nosnippet>261</a> <span class="kw">match </span>consumed.token {
<a href=#262 id=262 data-nosnippet>262</a> Token::LParen =&gt; paren_depth += <span class="number">1</span>,
<a href=#263 id=263 data-nosnippet>263</a> Token::RParen =&gt; {
<a href=#264 id=264 data-nosnippet>264</a> <span class="comment">// This RParen must belong to a nested expression since
<a href=#265 id=265 data-nosnippet>265</a> // `paren_depth &gt; 0` here. Decrease depth accordingly.
<a href=#266 id=266 data-nosnippet>266</a> </span>paren_depth = paren_depth.saturating_sub(<span class="number">1</span>);
<a href=#267 id=267 data-nosnippet>267</a> }
<a href=#268 id=268 data-nosnippet>268</a> <span class="kw">_ </span>=&gt; {}
<a href=#269 id=269 data-nosnippet>269</a> }
<a href=#270 id=270 data-nosnippet>270</a> }
<a href=#271 id=271 data-nosnippet>271</a>
<a href=#272 id=272 data-nosnippet>272</a> <span class="comment">// Extract the TQL query string directly from the original SQL
<a href=#273 id=273 data-nosnippet>273</a> </span><span class="kw">let </span>start_index = location_to_index(<span class="self">self</span>.sql, <span class="kw-2">&amp;</span>start_location);
<a href=#274 id=274 data-nosnippet>274</a> <span class="kw">let </span>end_index = location_to_index(<span class="self">self</span>.sql, <span class="kw-2">&amp;</span>end_location);
<a href=#275 id=275 data-nosnippet>275</a> <span class="kw">let </span>tql_string = <span class="kw-2">&amp;</span><span class="self">self</span>.sql[start_index..end_index];
<a href=#276 id=276 data-nosnippet>276</a> <span class="kw">let </span>tql_string = tql_string.trim();
<a href=#277 id=277 data-nosnippet>277</a>
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">let </span><span class="kw-2">mut </span>parser_ctx = ParserContext::new(<span class="kw-2">&amp;</span>GreptimeDbDialect {}, tql_string)<span class="question-mark">?</span>;
<a href=#279 id=279 data-nosnippet>279</a> parser_ctx.scheduled_time = <span class="self">self</span>.scheduled_time;
<a href=#280 id=280 data-nosnippet>280</a> <span class="kw">let </span>statement = parser_ctx.parse_tql(require_now_expr)<span class="question-mark">?</span>;
<a href=#281 id=281 data-nosnippet>281</a>
<a href=#282 id=282 data-nosnippet>282</a> <span class="kw">match </span>statement {
<a href=#283 id=283 data-nosnippet>283</a> Statement::Tql(Tql::Eval(eval)) =&gt; <span class="prelude-val">Ok</span>(Tql::Eval(eval)),
<a href=#284 id=284 data-nosnippet>284</a> Statement::Tql(<span class="kw">_</span>) =&gt; <span class="prelude-val">Err</span>(error::InvalidSqlSnafu {
<a href=#285 id=285 data-nosnippet>285</a> msg: <span class="string">"Only TQL EVAL is supported in CTEs"</span>.to_string(),
<a href=#286 id=286 data-nosnippet>286</a> }
<a href=#287 id=287 data-nosnippet>287</a> .build()),
<a href=#288 id=288 data-nosnippet>288</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">Err</span>(error::InvalidSqlSnafu {
<a href=#289 id=289 data-nosnippet>289</a> msg: <span class="string">"Expected a TQL statement inside CTE"</span>.to_string(),
<a href=#290 id=290 data-nosnippet>290</a> }
<a href=#291 id=291 data-nosnippet>291</a> .build()),
<a href=#292 id=292 data-nosnippet>292</a> }
<a href=#293 id=293 data-nosnippet>293</a> }
<a href=#294 id=294 data-nosnippet>294</a>}
<a href=#295 id=295 data-nosnippet>295</a>
<a href=#296 id=296 data-nosnippet>296</a><span class="attr">#[cfg(test)]
<a href=#297 id=297 data-nosnippet>297</a></span><span class="kw">mod </span>tests {
<a href=#298 id=298 data-nosnippet>298</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#299 id=299 data-nosnippet>299</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#300 id=300 data-nosnippet>300</a> <span class="kw">use </span><span class="kw">crate</span>::parsers::with_tql_parser::CteContent;
<a href=#301 id=301 data-nosnippet>301</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#302 id=302 data-nosnippet>302</a> <span class="kw">use </span><span class="kw">crate</span>::statements::tql::Tql;
<a href=#303 id=303 data-nosnippet>303</a>
<a href=#304 id=304 data-nosnippet>304</a> <span class="attr">#[test]
<a href=#305 id=305 data-nosnippet>305</a> </span><span class="kw">fn </span>test_parse_hybrid_cte_with_parentheses_in_query() {
<a href=#306 id=306 data-nosnippet>306</a> <span class="comment">// Test that parentheses within the TQL query don't interfere with CTE parsing
<a href=#307 id=307 data-nosnippet>307</a> </span><span class="kw">let </span>sql = <span class="string">r#"
<a href=#308 id=308 data-nosnippet>308</a> WITH tql_cte AS (
<a href=#309 id=309 data-nosnippet>309</a> TQL EVAL (0, 100, '5s')
<a href=#310 id=310 data-nosnippet>310</a> sum(rate(http_requests_total[1m])) + (max(cpu_usage) * (1 + 0.5))
<a href=#311 id=311 data-nosnippet>311</a> )
<a href=#312 id=312 data-nosnippet>312</a> SELECT * FROM tql_cte
<a href=#313 id=313 data-nosnippet>313</a> "#</span>;
<a href=#314 id=314 data-nosnippet>314</a>
<a href=#315 id=315 data-nosnippet>315</a> <span class="kw">let </span>statements =
<a href=#316 id=316 data-nosnippet>316</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#317 id=317 data-nosnippet>317</a> .unwrap();
<a href=#318 id=318 data-nosnippet>318</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#319 id=319 data-nosnippet>319</a>
<a href=#320 id=320 data-nosnippet>320</a> <span class="kw">let </span>Statement::Query(query) = <span class="kw-2">&amp;</span>statements[<span class="number">0</span>] <span class="kw">else </span>{
<a href=#321 id=321 data-nosnippet>321</a> <span class="macro">panic!</span>(<span class="string">"Expected Query statement"</span>);
<a href=#322 id=322 data-nosnippet>322</a> };
<a href=#323 id=323 data-nosnippet>323</a> <span class="kw">let </span>hybrid_cte = query.hybrid_cte.as_ref().unwrap();
<a href=#324 id=324 data-nosnippet>324</a> <span class="macro">assert_eq!</span>(hybrid_cte.cte_tables.len(), <span class="number">1</span>);
<a href=#325 id=325 data-nosnippet>325</a>
<a href=#326 id=326 data-nosnippet>326</a> <span class="comment">// Should be TQL content
<a href=#327 id=327 data-nosnippet>327</a> </span><span class="macro">assert!</span>(<span class="macro">matches!</span>(
<a href=#328 id=328 data-nosnippet>328</a> hybrid_cte.cte_tables[<span class="number">0</span>].content,
<a href=#329 id=329 data-nosnippet>329</a> CteContent::Tql(<span class="kw">_</span>)
<a href=#330 id=330 data-nosnippet>330</a> ));
<a href=#331 id=331 data-nosnippet>331</a>
<a href=#332 id=332 data-nosnippet>332</a> <span class="comment">// Check that the query includes the parentheses
<a href=#333 id=333 data-nosnippet>333</a> </span><span class="kw">if let </span>CteContent::Tql(Tql::Eval(eval)) = <span class="kw-2">&amp;</span>hybrid_cte.cte_tables[<span class="number">0</span>].content {
<a href=#334 id=334 data-nosnippet>334</a> <span class="comment">// Verify that complex nested parentheses are preserved correctly
<a href=#335 id=335 data-nosnippet>335</a> // The new approach preserves original spacing, so no extra spaces between tokens
<a href=#336 id=336 data-nosnippet>336</a> </span><span class="macro">assert!</span>(eval.query.contains(<span class="string">"sum(rate(http_requests_total[1m]))"</span>));
<a href=#337 id=337 data-nosnippet>337</a> <span class="macro">assert!</span>(eval.query.contains(<span class="string">"(max(cpu_usage) * (1 + 0.5))"</span>));
<a href=#338 id=338 data-nosnippet>338</a> <span class="comment">// Most importantly, verify the parentheses counting didn't break the parsing
<a href=#339 id=339 data-nosnippet>339</a> </span><span class="macro">assert!</span>(eval.query.contains(<span class="string">"+ (max"</span>));
<a href=#340 id=340 data-nosnippet>340</a> }
<a href=#341 id=341 data-nosnippet>341</a> }
<a href=#342 id=342 data-nosnippet>342</a>
<a href=#343 id=343 data-nosnippet>343</a> <span class="attr">#[test]
<a href=#344 id=344 data-nosnippet>344</a> </span><span class="kw">fn </span>test_parse_hybrid_cte_sql_and_tql() {
<a href=#345 id=345 data-nosnippet>345</a> <span class="kw">let </span>sql = <span class="string">r#"
<a href=#346 id=346 data-nosnippet>346</a> WITH
<a href=#347 id=347 data-nosnippet>347</a> sql_cte(ts, value, label) AS (SELECT timestamp, val, name FROM metrics),
<a href=#348 id=348 data-nosnippet>348</a> tql_cte(time, metric_value) AS (TQL EVAL (0, 100, '5s') cpu_usage)
<a href=#349 id=349 data-nosnippet>349</a> SELECT s.ts, s.value, t.metric_value
<a href=#350 id=350 data-nosnippet>350</a> FROM sql_cte s JOIN tql_cte t ON s.ts = t.time
<a href=#351 id=351 data-nosnippet>351</a> "#</span>;
<a href=#352 id=352 data-nosnippet>352</a>
<a href=#353 id=353 data-nosnippet>353</a> <span class="kw">let </span>statements =
<a href=#354 id=354 data-nosnippet>354</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#355 id=355 data-nosnippet>355</a> .unwrap();
<a href=#356 id=356 data-nosnippet>356</a> <span class="macro">assert_eq!</span>(statements.len(), <span class="number">1</span>);
<a href=#357 id=357 data-nosnippet>357</a>
<a href=#358 id=358 data-nosnippet>358</a> <span class="kw">let </span>Statement::Query(query) = <span class="kw-2">&amp;</span>statements[<span class="number">0</span>] <span class="kw">else </span>{
<a href=#359 id=359 data-nosnippet>359</a> <span class="macro">panic!</span>(<span class="string">"Expected Query statement"</span>);
<a href=#360 id=360 data-nosnippet>360</a> };
<a href=#361 id=361 data-nosnippet>361</a> <span class="kw">let </span>hybrid_cte = query.hybrid_cte.as_ref().unwrap();
<a href=#362 id=362 data-nosnippet>362</a> <span class="macro">assert_eq!</span>(hybrid_cte.cte_tables.len(), <span class="number">1</span>); <span class="comment">// only TQL CTE presents here
<a href=#363 id=363 data-nosnippet>363</a>
<a href=#364 id=364 data-nosnippet>364</a> // First CTE should be TQL with column aliases
<a href=#365 id=365 data-nosnippet>365</a> </span><span class="kw">let </span>second_cte = <span class="kw-2">&amp;</span>hybrid_cte.cte_tables[<span class="number">0</span>];
<a href=#366 id=366 data-nosnippet>366</a> <span class="macro">assert!</span>(<span class="macro">matches!</span>(second_cte.content, CteContent::Tql(<span class="kw">_</span>)));
<a href=#367 id=367 data-nosnippet>367</a> <span class="macro">assert_eq!</span>(second_cte.columns.len(), <span class="number">2</span>);
<a href=#368 id=368 data-nosnippet>368</a> <span class="macro">assert_eq!</span>(
<a href=#369 id=369 data-nosnippet>369</a> second_cte
<a href=#370 id=370 data-nosnippet>370</a> .columns
<a href=#371 id=371 data-nosnippet>371</a> .iter()
<a href=#372 id=372 data-nosnippet>372</a> .map(|x| x.to_string())
<a href=#373 id=373 data-nosnippet>373</a> .collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;()
<a href=#374 id=374 data-nosnippet>374</a> .join(<span class="string">" "</span>),
<a href=#375 id=375 data-nosnippet>375</a> <span class="string">"time metric_value"
<a href=#376 id=376 data-nosnippet>376</a> </span>);
<a href=#377 id=377 data-nosnippet>377</a> }
<a href=#378 id=378 data-nosnippet>378</a>}
</code></pre></div></section></main></body></html>
+327
View File
@@ -0,0 +1,327 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/partition.rs`."><title>partition.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>partition.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>snafu::ensure;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::{BinaryOperator, Expr, Ident, Value};
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span><span class="kw">crate</span>::error::{InvalidPartitionNumberSnafu, <span class="prelude-ty">Result</span>};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span><span class="kw">crate</span>::statements::create::Partitions;
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="doccomment">/// The default number of partitions for OpenTelemetry traces.
<a href=#22 id=22 data-nosnippet>22</a></span><span class="kw">const </span>DEFAULT_PARTITION_NUM_FOR_TRACES: u32 = <span class="number">16</span>;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="doccomment">/// The maximum number of partitions for OpenTelemetry traces.
<a href=#25 id=25 data-nosnippet>25</a></span><span class="kw">const </span>MAX_PARTITION_NUM_FOR_TRACES: u32 = <span class="number">65536</span>;
<a href=#26 id=26 data-nosnippet>26</a>
<a href=#27 id=27 data-nosnippet>27</a><span class="macro">macro_rules!</span> between_string {
<a href=#28 id=28 data-nosnippet>28</a> (<span class="macro-nonterminal">$col</span>: expr, <span class="macro-nonterminal">$left_incl</span>: expr, <span class="macro-nonterminal">$right_excl</span>: expr) =&gt; {
<a href=#29 id=29 data-nosnippet>29</a> Expr::BinaryOp {
<a href=#30 id=30 data-nosnippet>30</a> op: BinaryOperator::And,
<a href=#31 id=31 data-nosnippet>31</a> left: Box::new(Expr::BinaryOp {
<a href=#32 id=32 data-nosnippet>32</a> op: BinaryOperator::GtEq,
<a href=#33 id=33 data-nosnippet>33</a> left: Box::new(<span class="macro-nonterminal">$col</span>.clone()),
<a href=#34 id=34 data-nosnippet>34</a> right: Box::new(Expr::Value(
<a href=#35 id=35 data-nosnippet>35</a> Value::SingleQuotedString(<span class="macro-nonterminal">$left_incl</span>.to_string()).into(),
<a href=#36 id=36 data-nosnippet>36</a> )),
<a href=#37 id=37 data-nosnippet>37</a> }),
<a href=#38 id=38 data-nosnippet>38</a> right: Box::new(Expr::BinaryOp {
<a href=#39 id=39 data-nosnippet>39</a> op: BinaryOperator::Lt,
<a href=#40 id=40 data-nosnippet>40</a> left: Box::new(<span class="macro-nonterminal">$col</span>.clone()),
<a href=#41 id=41 data-nosnippet>41</a> right: Box::new(Expr::Value(
<a href=#42 id=42 data-nosnippet>42</a> Value::SingleQuotedString(<span class="macro-nonterminal">$right_excl</span>.to_string()).into(),
<a href=#43 id=43 data-nosnippet>43</a> )),
<a href=#44 id=44 data-nosnippet>44</a> }),
<a href=#45 id=45 data-nosnippet>45</a> }
<a href=#46 id=46 data-nosnippet>46</a> };
<a href=#47 id=47 data-nosnippet>47</a>}
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a><span class="kw">pub fn </span>partition_rule_for_hexstring(ident: <span class="kw-2">&amp;</span>str, partition_num: <span class="prelude-ty">Option</span>&lt;u32&gt;) -&gt; <span class="prelude-ty">Result</span>&lt;Partitions&gt; {
<a href=#50 id=50 data-nosnippet>50</a> <span class="prelude-val">Ok</span>(Partitions {
<a href=#51 id=51 data-nosnippet>51</a> column_list: <span class="macro">vec!</span>[Ident::new(ident)],
<a href=#52 id=52 data-nosnippet>52</a> exprs: partition_rules_for_uuid(
<a href=#53 id=53 data-nosnippet>53</a> partition_num.unwrap_or(DEFAULT_PARTITION_NUM_FOR_TRACES),
<a href=#54 id=54 data-nosnippet>54</a> ident,
<a href=#55 id=55 data-nosnippet>55</a> )<span class="question-mark">?</span>,
<a href=#56 id=56 data-nosnippet>56</a> })
<a href=#57 id=57 data-nosnippet>57</a>}
<a href=#58 id=58 data-nosnippet>58</a>
<a href=#59 id=59 data-nosnippet>59</a><span class="comment">// partition_rules_for_uuid can creates partition rules up to 65536 partitions.
<a href=#60 id=60 data-nosnippet>60</a></span><span class="kw">fn </span>partition_rules_for_uuid(partition_num: u32, ident: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;Expr&gt;&gt; {
<a href=#61 id=61 data-nosnippet>61</a> <span class="macro">ensure!</span>(
<a href=#62 id=62 data-nosnippet>62</a> partition_num.is_power_of_two() &amp;&amp; (<span class="number">2</span>..=<span class="number">65536</span>).contains(<span class="kw-2">&amp;</span>partition_num),
<a href=#63 id=63 data-nosnippet>63</a> InvalidPartitionNumberSnafu { partition_num }
<a href=#64 id=64 data-nosnippet>64</a> );
<a href=#65 id=65 data-nosnippet>65</a>
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">let </span>ident_expr = Expr::Identifier(Ident::new(ident).clone());
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a> <span class="kw">let </span>(total_partitions, hex_length) = {
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">match </span>partition_num {
<a href=#70 id=70 data-nosnippet>70</a> <span class="number">2</span>..=<span class="number">16 </span>=&gt; (<span class="number">16</span>, <span class="number">1</span>),
<a href=#71 id=71 data-nosnippet>71</a> <span class="number">17</span>..=<span class="number">256 </span>=&gt; (<span class="number">256</span>, <span class="number">2</span>),
<a href=#72 id=72 data-nosnippet>72</a> <span class="number">257</span>..=<span class="number">4096 </span>=&gt; (<span class="number">4096</span>, <span class="number">3</span>),
<a href=#73 id=73 data-nosnippet>73</a> <span class="number">4097</span>..=MAX_PARTITION_NUM_FOR_TRACES =&gt; (MAX_PARTITION_NUM_FOR_TRACES, <span class="number">4</span>),
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#75 id=75 data-nosnippet>75</a> }
<a href=#76 id=76 data-nosnippet>76</a> };
<a href=#77 id=77 data-nosnippet>77</a>
<a href=#78 id=78 data-nosnippet>78</a> <span class="kw">let </span>partition_size = total_partitions / partition_num;
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw">let </span>remainder = total_partitions % partition_num;
<a href=#80 id=80 data-nosnippet>80</a>
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">let </span><span class="kw-2">mut </span>rules = Vec::new();
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">let </span><span class="kw-2">mut </span>current_boundary = <span class="number">0</span>;
<a href=#83 id=83 data-nosnippet>83</a> <span class="kw">for </span>i <span class="kw">in </span><span class="number">0</span>..partition_num {
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw">let </span><span class="kw-2">mut </span>size = partition_size;
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">if </span>i &lt; remainder {
<a href=#86 id=86 data-nosnippet>86</a> size += <span class="number">1</span>;
<a href=#87 id=87 data-nosnippet>87</a> }
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">let </span>start = current_boundary;
<a href=#89 id=89 data-nosnippet>89</a> <span class="kw">let </span>end = current_boundary + size;
<a href=#90 id=90 data-nosnippet>90</a>
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">if </span>i == <span class="number">0 </span>{
<a href=#92 id=92 data-nosnippet>92</a> <span class="comment">// Create the leftmost rule, for example: trace_id &lt; '1'.
<a href=#93 id=93 data-nosnippet>93</a> </span>rules.push(Expr::BinaryOp {
<a href=#94 id=94 data-nosnippet>94</a> left: Box::new(ident_expr.clone()),
<a href=#95 id=95 data-nosnippet>95</a> op: BinaryOperator::Lt,
<a href=#96 id=96 data-nosnippet>96</a> right: Box::new(Expr::Value(
<a href=#97 id=97 data-nosnippet>97</a> Value::SingleQuotedString(<span class="macro">format!</span>(<span class="string">"{:0hex_length$x}"</span>, end)).into(),
<a href=#98 id=98 data-nosnippet>98</a> )),
<a href=#99 id=99 data-nosnippet>99</a> });
<a href=#100 id=100 data-nosnippet>100</a> } <span class="kw">else if </span>i == partition_num - <span class="number">1 </span>{
<a href=#101 id=101 data-nosnippet>101</a> <span class="comment">// Create the rightmost rule, for example: trace_id &gt;= 'f'.
<a href=#102 id=102 data-nosnippet>102</a> </span>rules.push(Expr::BinaryOp {
<a href=#103 id=103 data-nosnippet>103</a> left: Box::new(ident_expr.clone()),
<a href=#104 id=104 data-nosnippet>104</a> op: BinaryOperator::GtEq,
<a href=#105 id=105 data-nosnippet>105</a> right: Box::new(Expr::Value(
<a href=#106 id=106 data-nosnippet>106</a> Value::SingleQuotedString(<span class="macro">format!</span>(<span class="string">"{:0hex_length$x}"</span>, start)).into(),
<a href=#107 id=107 data-nosnippet>107</a> )),
<a href=#108 id=108 data-nosnippet>108</a> });
<a href=#109 id=109 data-nosnippet>109</a> } <span class="kw">else </span>{
<a href=#110 id=110 data-nosnippet>110</a> <span class="comment">// Create the middle rules, for example: trace_id &gt;= '1' AND trace_id &lt; '2'.
<a href=#111 id=111 data-nosnippet>111</a> </span>rules.push(<span class="macro">between_string!</span>(
<a href=#112 id=112 data-nosnippet>112</a> ident_expr,
<a href=#113 id=113 data-nosnippet>113</a> <span class="macro">format!</span>(<span class="string">"{:0hex_length$x}"</span>, start),
<a href=#114 id=114 data-nosnippet>114</a> <span class="macro">format!</span>(<span class="string">"{:0hex_length$x}"</span>, end)
<a href=#115 id=115 data-nosnippet>115</a> ));
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a>
<a href=#118 id=118 data-nosnippet>118</a> current_boundary = end;
<a href=#119 id=119 data-nosnippet>119</a> }
<a href=#120 id=120 data-nosnippet>120</a>
<a href=#121 id=121 data-nosnippet>121</a> <span class="prelude-val">Ok</span>(rules)
<a href=#122 id=122 data-nosnippet>122</a>}
<a href=#123 id=123 data-nosnippet>123</a>
<a href=#124 id=124 data-nosnippet>124</a><span class="attr">#[cfg(test)]
<a href=#125 id=125 data-nosnippet>125</a></span><span class="kw">mod </span>tests {
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">use </span>sqlparser::ast::{Expr, ValueWithSpan};
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">use </span>sqlparser::dialect::GenericDialect;
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">use </span>sqlparser::parser::Parser;
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">use </span>uuid::Uuid;
<a href=#130 id=130 data-nosnippet>130</a>
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#132 id=132 data-nosnippet>132</a>
<a href=#133 id=133 data-nosnippet>133</a> <span class="attr">#[test]
<a href=#134 id=134 data-nosnippet>134</a> </span><span class="kw">fn </span>test_partition_rules_for_uuid() {
<a href=#135 id=135 data-nosnippet>135</a> <span class="comment">// NOTE: We only test a subset of partitions to keep the test execution time reasonable.
<a href=#136 id=136 data-nosnippet>136</a> // As the number of partitions increases, we need to increase the number of test samples to ensure uniform distribution.
<a href=#137 id=137 data-nosnippet>137</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">2</span>, <span class="number">10_000</span>)); <span class="comment">// 2^1
<a href=#138 id=138 data-nosnippet>138</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">4</span>, <span class="number">10_000</span>)); <span class="comment">// 2^2
<a href=#139 id=139 data-nosnippet>139</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">8</span>, <span class="number">10_000</span>)); <span class="comment">// 2^3
<a href=#140 id=140 data-nosnippet>140</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">16</span>, <span class="number">10_000</span>)); <span class="comment">// 2^4
<a href=#141 id=141 data-nosnippet>141</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">32</span>, <span class="number">10_000</span>)); <span class="comment">// 2^5
<a href=#142 id=142 data-nosnippet>142</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">64</span>, <span class="number">100_000</span>)); <span class="comment">// 2^6
<a href=#143 id=143 data-nosnippet>143</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">128</span>, <span class="number">100_000</span>)); <span class="comment">// 2^7
<a href=#144 id=144 data-nosnippet>144</a> </span><span class="macro">assert!</span>(check_distribution(<span class="number">256</span>, <span class="number">100_000</span>)); <span class="comment">// 2^8
<a href=#145 id=145 data-nosnippet>145</a> </span>}
<a href=#146 id=146 data-nosnippet>146</a>
<a href=#147 id=147 data-nosnippet>147</a> <span class="attr">#[test]
<a href=#148 id=148 data-nosnippet>148</a> </span><span class="kw">fn </span>test_rules() {
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw">let </span>expr = <span class="macro">vec!</span>[
<a href=#150 id=150 data-nosnippet>150</a> <span class="string">"trace_id &lt; '1'"</span>,
<a href=#151 id=151 data-nosnippet>151</a> <span class="string">"trace_id &gt;= '1' AND trace_id &lt; '2'"</span>,
<a href=#152 id=152 data-nosnippet>152</a> <span class="string">"trace_id &gt;= '2' AND trace_id &lt; '3'"</span>,
<a href=#153 id=153 data-nosnippet>153</a> <span class="string">"trace_id &gt;= '3' AND trace_id &lt; '4'"</span>,
<a href=#154 id=154 data-nosnippet>154</a> <span class="string">"trace_id &gt;= '4' AND trace_id &lt; '5'"</span>,
<a href=#155 id=155 data-nosnippet>155</a> <span class="string">"trace_id &gt;= '5' AND trace_id &lt; '6'"</span>,
<a href=#156 id=156 data-nosnippet>156</a> <span class="string">"trace_id &gt;= '6' AND trace_id &lt; '7'"</span>,
<a href=#157 id=157 data-nosnippet>157</a> <span class="string">"trace_id &gt;= '7' AND trace_id &lt; '8'"</span>,
<a href=#158 id=158 data-nosnippet>158</a> <span class="string">"trace_id &gt;= '8' AND trace_id &lt; '9'"</span>,
<a href=#159 id=159 data-nosnippet>159</a> <span class="string">"trace_id &gt;= '9' AND trace_id &lt; 'a'"</span>,
<a href=#160 id=160 data-nosnippet>160</a> <span class="string">"trace_id &gt;= 'a' AND trace_id &lt; 'b'"</span>,
<a href=#161 id=161 data-nosnippet>161</a> <span class="string">"trace_id &gt;= 'b' AND trace_id &lt; 'c'"</span>,
<a href=#162 id=162 data-nosnippet>162</a> <span class="string">"trace_id &gt;= 'c' AND trace_id &lt; 'd'"</span>,
<a href=#163 id=163 data-nosnippet>163</a> <span class="string">"trace_id &gt;= 'd' AND trace_id &lt; 'e'"</span>,
<a href=#164 id=164 data-nosnippet>164</a> <span class="string">"trace_id &gt;= 'e' AND trace_id &lt; 'f'"</span>,
<a href=#165 id=165 data-nosnippet>165</a> <span class="string">"trace_id &gt;= 'f'"</span>,
<a href=#166 id=166 data-nosnippet>166</a> ];
<a href=#167 id=167 data-nosnippet>167</a>
<a href=#168 id=168 data-nosnippet>168</a> <span class="kw">let </span>dialect = GenericDialect {};
<a href=#169 id=169 data-nosnippet>169</a> <span class="kw">let </span>results = expr
<a href=#170 id=170 data-nosnippet>170</a> .into_iter()
<a href=#171 id=171 data-nosnippet>171</a> .map(|s| {
<a href=#172 id=172 data-nosnippet>172</a> <span class="kw">let </span><span class="kw-2">mut </span>parser = Parser::new(<span class="kw-2">&amp;</span>dialect).try_with_sql(s).unwrap();
<a href=#173 id=173 data-nosnippet>173</a> parser.parse_expr().unwrap()
<a href=#174 id=174 data-nosnippet>174</a> })
<a href=#175 id=175 data-nosnippet>175</a> .collect::&lt;Vec&lt;Expr&gt;&gt;();
<a href=#176 id=176 data-nosnippet>176</a>
<a href=#177 id=177 data-nosnippet>177</a> <span class="macro">assert_eq!</span>(
<a href=#178 id=178 data-nosnippet>178</a> results,
<a href=#179 id=179 data-nosnippet>179</a> partition_rule_for_hexstring(<span class="string">"trace_id"</span>, <span class="prelude-val">None</span>)
<a href=#180 id=180 data-nosnippet>180</a> .unwrap()
<a href=#181 id=181 data-nosnippet>181</a> .exprs
<a href=#182 id=182 data-nosnippet>182</a> );
<a href=#183 id=183 data-nosnippet>183</a>
<a href=#184 id=184 data-nosnippet>184</a> <span class="comment">// custom partition number
<a href=#185 id=185 data-nosnippet>185</a> </span><span class="kw">let </span>expr = <span class="macro">vec!</span>[
<a href=#186 id=186 data-nosnippet>186</a> <span class="string">"trace_id &lt; '4'"</span>,
<a href=#187 id=187 data-nosnippet>187</a> <span class="string">"trace_id &gt;= '4' AND trace_id &lt; '8'"</span>,
<a href=#188 id=188 data-nosnippet>188</a> <span class="string">"trace_id &gt;= '8' AND trace_id &lt; 'c'"</span>,
<a href=#189 id=189 data-nosnippet>189</a> <span class="string">"trace_id &gt;= 'c'"</span>,
<a href=#190 id=190 data-nosnippet>190</a> ];
<a href=#191 id=191 data-nosnippet>191</a> <span class="kw">let </span>results = expr
<a href=#192 id=192 data-nosnippet>192</a> .into_iter()
<a href=#193 id=193 data-nosnippet>193</a> .map(|s| {
<a href=#194 id=194 data-nosnippet>194</a> <span class="kw">let </span><span class="kw-2">mut </span>parser = Parser::new(<span class="kw-2">&amp;</span>dialect).try_with_sql(s).unwrap();
<a href=#195 id=195 data-nosnippet>195</a> parser.parse_expr().unwrap()
<a href=#196 id=196 data-nosnippet>196</a> })
<a href=#197 id=197 data-nosnippet>197</a> .collect::&lt;Vec&lt;Expr&gt;&gt;();
<a href=#198 id=198 data-nosnippet>198</a> <span class="macro">assert_eq!</span>(
<a href=#199 id=199 data-nosnippet>199</a> results,
<a href=#200 id=200 data-nosnippet>200</a> partition_rule_for_hexstring(<span class="string">"trace_id"</span>, <span class="prelude-val">Some</span>(<span class="number">4</span>))
<a href=#201 id=201 data-nosnippet>201</a> .unwrap()
<a href=#202 id=202 data-nosnippet>202</a> .exprs
<a href=#203 id=203 data-nosnippet>203</a> );
<a href=#204 id=204 data-nosnippet>204</a> }
<a href=#205 id=205 data-nosnippet>205</a>
<a href=#206 id=206 data-nosnippet>206</a> <span class="kw">fn </span>check_distribution(test_partition: u32, test_uuid_num: usize) -&gt; bool {
<a href=#207 id=207 data-nosnippet>207</a> <span class="comment">// Generate the partition rules.
<a href=#208 id=208 data-nosnippet>208</a> </span><span class="kw">let </span>rules = partition_rules_for_uuid(test_partition, <span class="string">"test_trace_id"</span>).unwrap();
<a href=#209 id=209 data-nosnippet>209</a> <span class="kw">let </span>upper_bounds = upper_bounds_from_rules(<span class="kw-2">&amp;</span>rules);
<a href=#210 id=210 data-nosnippet>210</a>
<a href=#211 id=211 data-nosnippet>211</a> <span class="comment">// Collect the number of partitions for each uuid.
<a href=#212 id=212 data-nosnippet>212</a> </span><span class="kw">let </span><span class="kw-2">mut </span>counts = <span class="macro">vec!</span>[<span class="number">0usize</span>; test_partition <span class="kw">as </span>usize];
<a href=#213 id=213 data-nosnippet>213</a> <span class="kw">for _ in </span><span class="number">0</span>..test_uuid_num {
<a href=#214 id=214 data-nosnippet>214</a> <span class="kw">let </span>uuid = Uuid::new_v4().simple().to_string();
<a href=#215 id=215 data-nosnippet>215</a> <span class="kw">let </span>partition = allocate_partition_for_uuid(uuid.as_str(), <span class="kw-2">&amp;</span>upper_bounds);
<a href=#216 id=216 data-nosnippet>216</a> counts[partition] += <span class="number">1</span>;
<a href=#217 id=217 data-nosnippet>217</a> }
<a href=#218 id=218 data-nosnippet>218</a>
<a href=#219 id=219 data-nosnippet>219</a> <span class="comment">// Check if the partition distribution is uniform.
<a href=#220 id=220 data-nosnippet>220</a> </span><span class="kw">let </span>expected_ratio = <span class="number">100.0 </span>/ test_partition <span class="kw">as </span>f64;
<a href=#221 id=221 data-nosnippet>221</a>
<a href=#222 id=222 data-nosnippet>222</a> <span class="comment">// tolerance is the allowed deviation from the expected ratio.
<a href=#223 id=223 data-nosnippet>223</a> </span><span class="kw">let </span>tolerance = <span class="number">100.0 </span>/ test_partition <span class="kw">as </span>f64 * <span class="number">0.30</span>;
<a href=#224 id=224 data-nosnippet>224</a>
<a href=#225 id=225 data-nosnippet>225</a> <span class="comment">// For each partition, its ratio should be as close as possible to the expected ratio.
<a href=#226 id=226 data-nosnippet>226</a> </span><span class="kw">for </span>count <span class="kw">in </span>counts {
<a href=#227 id=227 data-nosnippet>227</a> <span class="kw">let </span>ratio = (count <span class="kw">as </span>f64 / test_uuid_num <span class="kw">as </span>f64) * <span class="number">100.0</span>;
<a href=#228 id=228 data-nosnippet>228</a> <span class="kw">if </span>(ratio - expected_ratio).abs() &gt;= tolerance {
<a href=#229 id=229 data-nosnippet>229</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#230 id=230 data-nosnippet>230</a> }
<a href=#231 id=231 data-nosnippet>231</a> }
<a href=#232 id=232 data-nosnippet>232</a>
<a href=#233 id=233 data-nosnippet>233</a> <span class="bool-val">true
<a href=#234 id=234 data-nosnippet>234</a> </span>}
<a href=#235 id=235 data-nosnippet>235</a>
<a href=#236 id=236 data-nosnippet>236</a> <span class="kw">fn </span>upper_bounds_from_rules&lt;<span class="lifetime">'a</span>&gt;(rules: <span class="kw-2">&amp;</span><span class="lifetime">'a </span>[Expr]) -&gt; Vec&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt; {
<a href=#237 id=237 data-nosnippet>237</a> <span class="kw">let </span><span class="kw-2">mut </span>upper_bounds = Vec::with_capacity(rules.len().saturating_sub(<span class="number">1</span>));
<a href=#238 id=238 data-nosnippet>238</a> <span class="kw">let </span><span class="kw-2">mut </span>prev_upper: <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt; = <span class="prelude-val">None</span>;
<a href=#239 id=239 data-nosnippet>239</a>
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">for </span>(idx, rule) <span class="kw">in </span>rules.iter().enumerate() {
<a href=#241 id=241 data-nosnippet>241</a> <span class="kw">let </span>(lower, upper) = extract_rule_bounds(rule);
<a href=#242 id=242 data-nosnippet>242</a> <span class="kw">match </span>idx {
<a href=#243 id=243 data-nosnippet>243</a> <span class="number">0 </span>=&gt; {
<a href=#244 id=244 data-nosnippet>244</a> <span class="macro">assert!</span>(lower.is_none());
<a href=#245 id=245 data-nosnippet>245</a> <span class="macro">assert!</span>(upper.is_some());
<a href=#246 id=246 data-nosnippet>246</a> }
<a href=#247 id=247 data-nosnippet>247</a> idx <span class="kw">if </span>idx == rules.len() - <span class="number">1 </span>=&gt; {
<a href=#248 id=248 data-nosnippet>248</a> <span class="macro">assert_eq!</span>(lower, prev_upper);
<a href=#249 id=249 data-nosnippet>249</a> <span class="macro">assert!</span>(upper.is_none());
<a href=#250 id=250 data-nosnippet>250</a> }
<a href=#251 id=251 data-nosnippet>251</a> <span class="kw">_ </span>=&gt; {
<a href=#252 id=252 data-nosnippet>252</a> <span class="macro">assert_eq!</span>(lower, prev_upper);
<a href=#253 id=253 data-nosnippet>253</a> <span class="macro">assert!</span>(upper.is_some());
<a href=#254 id=254 data-nosnippet>254</a> }
<a href=#255 id=255 data-nosnippet>255</a> }
<a href=#256 id=256 data-nosnippet>256</a>
<a href=#257 id=257 data-nosnippet>257</a> <span class="kw">if </span>idx &lt; rules.len() - <span class="number">1 </span>{
<a href=#258 id=258 data-nosnippet>258</a> upper_bounds.push(upper.unwrap());
<a href=#259 id=259 data-nosnippet>259</a> }
<a href=#260 id=260 data-nosnippet>260</a>
<a href=#261 id=261 data-nosnippet>261</a> prev_upper = upper;
<a href=#262 id=262 data-nosnippet>262</a> }
<a href=#263 id=263 data-nosnippet>263</a>
<a href=#264 id=264 data-nosnippet>264</a> upper_bounds
<a href=#265 id=265 data-nosnippet>265</a> }
<a href=#266 id=266 data-nosnippet>266</a>
<a href=#267 id=267 data-nosnippet>267</a> <span class="kw">fn </span>extract_rule_bounds(rule: <span class="kw-2">&amp;</span>Expr) -&gt; (<span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>str&gt;, <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>str&gt;) {
<a href=#268 id=268 data-nosnippet>268</a> <span class="kw">fn </span>extract_single_quoted_string(expr: <span class="kw-2">&amp;</span>Expr) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>str&gt; {
<a href=#269 id=269 data-nosnippet>269</a> <span class="kw">match </span>expr {
<a href=#270 id=270 data-nosnippet>270</a> Expr::Value(ValueWithSpan {
<a href=#271 id=271 data-nosnippet>271</a> value: Value::SingleQuotedString(value),
<a href=#272 id=272 data-nosnippet>272</a> ..
<a href=#273 id=273 data-nosnippet>273</a> }) =&gt; <span class="prelude-val">Some</span>(value.as_str()),
<a href=#274 id=274 data-nosnippet>274</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#275 id=275 data-nosnippet>275</a> }
<a href=#276 id=276 data-nosnippet>276</a> }
<a href=#277 id=277 data-nosnippet>277</a>
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">match </span>rule {
<a href=#279 id=279 data-nosnippet>279</a> Expr::BinaryOp {
<a href=#280 id=280 data-nosnippet>280</a> op: BinaryOperator::Lt,
<a href=#281 id=281 data-nosnippet>281</a> right,
<a href=#282 id=282 data-nosnippet>282</a> ..
<a href=#283 id=283 data-nosnippet>283</a> } =&gt; (<span class="prelude-val">None</span>, extract_single_quoted_string(right)),
<a href=#284 id=284 data-nosnippet>284</a> Expr::BinaryOp {
<a href=#285 id=285 data-nosnippet>285</a> op: BinaryOperator::GtEq,
<a href=#286 id=286 data-nosnippet>286</a> right,
<a href=#287 id=287 data-nosnippet>287</a> ..
<a href=#288 id=288 data-nosnippet>288</a> } =&gt; (extract_single_quoted_string(right), <span class="prelude-val">None</span>),
<a href=#289 id=289 data-nosnippet>289</a> Expr::BinaryOp {
<a href=#290 id=290 data-nosnippet>290</a> op: BinaryOperator::And,
<a href=#291 id=291 data-nosnippet>291</a> left,
<a href=#292 id=292 data-nosnippet>292</a> right,
<a href=#293 id=293 data-nosnippet>293</a> } =&gt; {
<a href=#294 id=294 data-nosnippet>294</a> <span class="kw">let </span>lower = <span class="kw">match </span>left.as_ref() {
<a href=#295 id=295 data-nosnippet>295</a> Expr::BinaryOp {
<a href=#296 id=296 data-nosnippet>296</a> op: BinaryOperator::GtEq,
<a href=#297 id=297 data-nosnippet>297</a> right,
<a href=#298 id=298 data-nosnippet>298</a> ..
<a href=#299 id=299 data-nosnippet>299</a> } =&gt; extract_single_quoted_string(right),
<a href=#300 id=300 data-nosnippet>300</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#301 id=301 data-nosnippet>301</a> };
<a href=#302 id=302 data-nosnippet>302</a> <span class="kw">let </span>upper = <span class="kw">match </span>right.as_ref() {
<a href=#303 id=303 data-nosnippet>303</a> Expr::BinaryOp {
<a href=#304 id=304 data-nosnippet>304</a> op: BinaryOperator::Lt,
<a href=#305 id=305 data-nosnippet>305</a> right,
<a href=#306 id=306 data-nosnippet>306</a> ..
<a href=#307 id=307 data-nosnippet>307</a> } =&gt; extract_single_quoted_string(right),
<a href=#308 id=308 data-nosnippet>308</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#309 id=309 data-nosnippet>309</a> };
<a href=#310 id=310 data-nosnippet>310</a> (lower, upper)
<a href=#311 id=311 data-nosnippet>311</a> }
<a href=#312 id=312 data-nosnippet>312</a> <span class="kw">_ </span>=&gt; (<span class="prelude-val">None</span>, <span class="prelude-val">None</span>),
<a href=#313 id=313 data-nosnippet>313</a> }
<a href=#314 id=314 data-nosnippet>314</a> }
<a href=#315 id=315 data-nosnippet>315</a>
<a href=#316 id=316 data-nosnippet>316</a> <span class="kw">fn </span>allocate_partition_for_uuid(uuid: <span class="kw-2">&amp;</span>str, upper_bounds: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span>str]) -&gt; usize {
<a href=#317 id=317 data-nosnippet>317</a> upper_bounds.partition_point(|upper| uuid &gt;= <span class="kw-2">*</span>upper)
<a href=#318 id=318 data-nosnippet>318</a> }
<a href=#319 id=319 data-nosnippet>319</a>
<a href=#320 id=320 data-nosnippet>320</a> <span class="attr">#[test]
<a href=#321 id=321 data-nosnippet>321</a> </span><span class="kw">fn </span>test_extract_rule_bounds() {
<a href=#322 id=322 data-nosnippet>322</a> <span class="kw">let </span>rules = partition_rules_for_uuid(<span class="number">16</span>, <span class="string">"trace_id"</span>).unwrap();
<a href=#323 id=323 data-nosnippet>323</a> <span class="kw">let </span>upper_bounds = upper_bounds_from_rules(<span class="kw-2">&amp;</span>rules);
<a href=#324 id=324 data-nosnippet>324</a> <span class="macro">assert_eq!</span>(upper_bounds.len(), <span class="number">15</span>);
<a href=#325 id=325 data-nosnippet>325</a> }
<a href=#326 id=326 data-nosnippet>326</a>}
</code></pre></div></section></main></body></html>
+836
View File
@@ -0,0 +1,836 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements.rs`."><title>statements.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../static.files/storage-41dd4d93.js"></script><script defer src="../../static.files/src-script-813739b1.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/</div>statements.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">pub mod </span>admin;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">pub mod </span>alter;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">pub mod </span>comment;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">pub mod </span>copy;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">pub mod </span>create;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">pub mod </span>cursor;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">pub mod </span>delete;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">pub mod </span>describe;
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">pub mod </span>drop;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">pub mod </span>explain;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">pub mod </span>insert;
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">pub mod </span>kill;
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">mod </span>option_map;
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">pub mod </span>query;
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">pub mod </span>set_variables;
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">pub mod </span>show;
<a href=#31 id=31 data-nosnippet>31</a><span class="kw">pub mod </span>statement;
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">pub mod </span>tql;
<a href=#33 id=33 data-nosnippet>33</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>transform;
<a href=#34 id=34 data-nosnippet>34</a><span class="kw">pub mod </span>truncate;
<a href=#35 id=35 data-nosnippet>35</a>
<a href=#36 id=36 data-nosnippet>36</a><span class="kw">use </span>std::sync::Arc;
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">use </span>api::helper::ColumnDataTypeWrapper;
<a href=#39 id=39 data-nosnippet>39</a><span class="kw">use </span>api::v1::{ColumnOptions, SemanticType};
<a href=#40 id=40 data-nosnippet>40</a><span class="kw">use </span>arrow_schema::extension::{
<a href=#41 id=41 data-nosnippet>41</a> EXTENSION_TYPE_METADATA_KEY, EXTENSION_TYPE_NAME_KEY, ExtensionType,
<a href=#42 id=42 data-nosnippet>42</a>};
<a href=#43 id=43 data-nosnippet>43</a><span class="kw">use </span>common_sql::default_constraint::parse_column_default_constraint;
<a href=#44 id=44 data-nosnippet>44</a><span class="kw">use </span>common_time::timezone::Timezone;
<a href=#45 id=45 data-nosnippet>45</a><span class="kw">use </span>datatypes::extension::json::{Json2ExtensionType, JsonMetadata};
<a href=#46 id=46 data-nosnippet>46</a><span class="kw">use </span>datatypes::json::JsonSettings;
<a href=#47 id=47 data-nosnippet>47</a><span class="kw">use </span>datatypes::prelude::ConcreteDataType;
<a href=#48 id=48 data-nosnippet>48</a><span class="kw">use </span>datatypes::schema::{COMMENT_KEY, ColumnDefaultConstraint, ColumnSchema};
<a href=#49 id=49 data-nosnippet>49</a><span class="kw">use </span>datatypes::types::json_type::JsonNativeType;
<a href=#50 id=50 data-nosnippet>50</a><span class="kw">use </span>datatypes::types::{JsonFormat, JsonType, TimestampType};
<a href=#51 id=51 data-nosnippet>51</a><span class="kw">use </span>datatypes::value::Value;
<a href=#52 id=52 data-nosnippet>52</a><span class="kw">use </span>snafu::ResultExt;
<a href=#53 id=53 data-nosnippet>53</a><span class="kw">use </span>sqlparser::ast::{ExactNumberInfo, Ident};
<a href=#54 id=54 data-nosnippet>54</a>
<a href=#55 id=55 data-nosnippet>55</a><span class="kw">use </span><span class="kw">crate</span>::ast::{
<a href=#56 id=56 data-nosnippet>56</a> ColumnDef, ColumnOption, DataType <span class="kw">as </span>SqlDataType, ObjectNamePartExt, TimezoneInfo,
<a href=#57 id=57 data-nosnippet>57</a> Value <span class="kw">as </span>SqlValue,
<a href=#58 id=58 data-nosnippet>58</a>};
<a href=#59 id=59 data-nosnippet>59</a><span class="kw">use </span><span class="kw">crate</span>::error::{
<a href=#60 id=60 data-nosnippet>60</a> <span class="self">self</span>, ConvertToGrpcDataTypeSnafu, ConvertValueSnafu, <span class="prelude-ty">Result</span>,
<a href=#61 id=61 data-nosnippet>61</a> SerializeColumnDefaultConstraintSnafu, SetCompressionOptionSnafu, SetFulltextOptionSnafu,
<a href=#62 id=62 data-nosnippet>62</a> SetSkippingIndexOptionSnafu, SqlCommonSnafu,
<a href=#63 id=63 data-nosnippet>63</a>};
<a href=#64 id=64 data-nosnippet>64</a><span class="kw">use </span><span class="kw">crate</span>::statements::create::Column;
<a href=#65 id=65 data-nosnippet>65</a><span class="kw">pub use </span><span class="kw">crate</span>::statements::option_map::OptionMap;
<a href=#66 id=66 data-nosnippet>66</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">use </span><span class="kw">crate</span>::statements::transform::transform_statements;
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a><span class="kw">const </span>VECTOR_TYPE_NAME: <span class="kw-2">&amp;</span>str = <span class="string">"VECTOR"</span>;
<a href=#69 id=69 data-nosnippet>69</a><span class="kw">const </span>JSON2_TYPE_NAME: <span class="kw-2">&amp;</span>str = <span class="string">"JSON2"</span>;
<a href=#70 id=70 data-nosnippet>70</a>
<a href=#71 id=71 data-nosnippet>71</a><span class="kw">pub fn </span>value_to_sql_value(val: <span class="kw-2">&amp;</span>Value) -&gt; <span class="prelude-ty">Result</span>&lt;SqlValue&gt; {
<a href=#72 id=72 data-nosnippet>72</a> <span class="prelude-val">Ok</span>(<span class="kw">match </span>val {
<a href=#73 id=73 data-nosnippet>73</a> Value::Int8(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#74 id=74 data-nosnippet>74</a> Value::UInt8(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#75 id=75 data-nosnippet>75</a> Value::Int16(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#76 id=76 data-nosnippet>76</a> Value::UInt16(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#77 id=77 data-nosnippet>77</a> Value::Int32(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#78 id=78 data-nosnippet>78</a> Value::UInt32(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#79 id=79 data-nosnippet>79</a> Value::Int64(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#80 id=80 data-nosnippet>80</a> Value::UInt64(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#81 id=81 data-nosnippet>81</a> Value::Float32(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#82 id=82 data-nosnippet>82</a> Value::Float64(v) =&gt; SqlValue::Number(v.to_string(), <span class="bool-val">false</span>),
<a href=#83 id=83 data-nosnippet>83</a> Value::Boolean(b) =&gt; SqlValue::Boolean(<span class="kw-2">*</span>b),
<a href=#84 id=84 data-nosnippet>84</a> Value::Date(d) =&gt; SqlValue::SingleQuotedString(d.to_string()),
<a href=#85 id=85 data-nosnippet>85</a> Value::Timestamp(ts) =&gt; SqlValue::SingleQuotedString(ts.to_iso8601_string()),
<a href=#86 id=86 data-nosnippet>86</a> Value::String(s) =&gt; SqlValue::SingleQuotedString(s.as_utf8().to_string()),
<a href=#87 id=87 data-nosnippet>87</a> Value::Null =&gt; SqlValue::Null,
<a href=#88 id=88 data-nosnippet>88</a> <span class="comment">// TODO(dennis): supports binary
<a href=#89 id=89 data-nosnippet>89</a> </span><span class="kw">_ </span>=&gt; <span class="kw">return </span>ConvertValueSnafu { value: val.clone() }.fail(),
<a href=#90 id=90 data-nosnippet>90</a> })
<a href=#91 id=91 data-nosnippet>91</a>}
<a href=#92 id=92 data-nosnippet>92</a>
<a href=#93 id=93 data-nosnippet>93</a><span class="doccomment">/// Return true when the `ColumnDef` options contain primary key
<a href=#94 id=94 data-nosnippet>94</a></span><span class="kw">pub fn </span>has_primary_key_option(column_def: <span class="kw-2">&amp;</span>ColumnDef) -&gt; bool {
<a href=#95 id=95 data-nosnippet>95</a> column_def
<a href=#96 id=96 data-nosnippet>96</a> .options
<a href=#97 id=97 data-nosnippet>97</a> .iter()
<a href=#98 id=98 data-nosnippet>98</a> .any(|options| <span class="macro">matches!</span>(options.option, ColumnOption::PrimaryKey(..)))
<a href=#99 id=99 data-nosnippet>99</a>}
<a href=#100 id=100 data-nosnippet>100</a>
<a href=#101 id=101 data-nosnippet>101</a><span class="doccomment">/// Create a `ColumnSchema` from `Column`.
<a href=#102 id=102 data-nosnippet>102</a></span><span class="kw">pub fn </span>column_to_schema(
<a href=#103 id=103 data-nosnippet>103</a> column: <span class="kw-2">&amp;</span>Column,
<a href=#104 id=104 data-nosnippet>104</a> time_index: <span class="kw-2">&amp;</span>str,
<a href=#105 id=105 data-nosnippet>105</a> timezone: <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>Timezone&gt;,
<a href=#106 id=106 data-nosnippet>106</a>) -&gt; <span class="prelude-ty">Result</span>&lt;ColumnSchema&gt; {
<a href=#107 id=107 data-nosnippet>107</a> <span class="kw">let </span>is_time_index = column.name().value == time_index;
<a href=#108 id=108 data-nosnippet>108</a>
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw">let </span>is_nullable = column
<a href=#110 id=110 data-nosnippet>110</a> .options()
<a href=#111 id=111 data-nosnippet>111</a> .iter()
<a href=#112 id=112 data-nosnippet>112</a> .all(|o| !<span class="macro">matches!</span>(o.option, ColumnOption::NotNull))
<a href=#113 id=113 data-nosnippet>113</a> &amp;&amp; !is_time_index;
<a href=#114 id=114 data-nosnippet>114</a>
<a href=#115 id=115 data-nosnippet>115</a> <span class="kw">let </span>name = column.name().value.clone();
<a href=#116 id=116 data-nosnippet>116</a> <span class="kw">let </span>data_type = sql_data_type_to_concrete_data_type(column.data_type())<span class="question-mark">?</span>;
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">let </span>default_constraint =
<a href=#118 id=118 data-nosnippet>118</a> parse_column_default_constraint(<span class="kw-2">&amp;</span>name, <span class="kw-2">&amp;</span>data_type, column.options(), timezone)
<a href=#119 id=119 data-nosnippet>119</a> .context(SqlCommonSnafu)<span class="question-mark">?</span>;
<a href=#120 id=120 data-nosnippet>120</a>
<a href=#121 id=121 data-nosnippet>121</a> <span class="kw">let </span><span class="kw-2">mut </span>column_schema = ColumnSchema::new(name, data_type, is_nullable)
<a href=#122 id=122 data-nosnippet>122</a> .with_time_index(is_time_index)
<a href=#123 id=123 data-nosnippet>123</a> .with_default_constraint(default_constraint)
<a href=#124 id=124 data-nosnippet>124</a> .context(error::InvalidDefaultSnafu {
<a href=#125 id=125 data-nosnippet>125</a> column: <span class="kw-2">&amp;</span>column.name().value,
<a href=#126 id=126 data-nosnippet>126</a> })<span class="question-mark">?</span>;
<a href=#127 id=127 data-nosnippet>127</a>
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(ColumnOption::Comment(c)) = column.options().iter().find_map(|o| {
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">if </span><span class="macro">matches!</span>(o.option, ColumnOption::Comment(<span class="kw">_</span>)) {
<a href=#130 id=130 data-nosnippet>130</a> <span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>o.option)
<a href=#131 id=131 data-nosnippet>131</a> } <span class="kw">else </span>{
<a href=#132 id=132 data-nosnippet>132</a> <span class="prelude-val">None
<a href=#133 id=133 data-nosnippet>133</a> </span>}
<a href=#134 id=134 data-nosnippet>134</a> }) {
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">let _ </span>= column_schema
<a href=#136 id=136 data-nosnippet>136</a> .mut_metadata()
<a href=#137 id=137 data-nosnippet>137</a> .insert(COMMENT_KEY.to_string(), c.clone());
<a href=#138 id=138 data-nosnippet>138</a> }
<a href=#139 id=139 data-nosnippet>139</a>
<a href=#140 id=140 data-nosnippet>140</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(options) = column.extensions.build_fulltext_options()<span class="question-mark">? </span>{
<a href=#141 id=141 data-nosnippet>141</a> column_schema = column_schema
<a href=#142 id=142 data-nosnippet>142</a> .with_fulltext_options(options)
<a href=#143 id=143 data-nosnippet>143</a> .context(SetFulltextOptionSnafu)<span class="question-mark">?</span>;
<a href=#144 id=144 data-nosnippet>144</a> }
<a href=#145 id=145 data-nosnippet>145</a>
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(options) = column.extensions.build_skipping_index_options()<span class="question-mark">? </span>{
<a href=#147 id=147 data-nosnippet>147</a> column_schema = column_schema
<a href=#148 id=148 data-nosnippet>148</a> .with_skipping_options(options)
<a href=#149 id=149 data-nosnippet>149</a> .context(SetSkippingIndexOptionSnafu)<span class="question-mark">?</span>;
<a href=#150 id=150 data-nosnippet>150</a> }
<a href=#151 id=151 data-nosnippet>151</a>
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(options) = column.extensions.build_compression_options()<span class="question-mark">? </span>{
<a href=#153 id=153 data-nosnippet>153</a> column_schema = column_schema
<a href=#154 id=154 data-nosnippet>154</a> .with_compression_options(options)
<a href=#155 id=155 data-nosnippet>155</a> .context(SetCompressionOptionSnafu)<span class="question-mark">?</span>;
<a href=#156 id=156 data-nosnippet>156</a> }
<a href=#157 id=157 data-nosnippet>157</a>
<a href=#158 id=158 data-nosnippet>158</a> column_schema.set_inverted_index(column.extensions.inverted_index_options.is_some());
<a href=#159 id=159 data-nosnippet>159</a>
<a href=#160 id=160 data-nosnippet>160</a> set_json2_extension(<span class="kw-2">&amp;mut </span>column_schema, column)<span class="question-mark">?</span>;
<a href=#161 id=161 data-nosnippet>161</a>
<a href=#162 id=162 data-nosnippet>162</a> <span class="prelude-val">Ok</span>(column_schema)
<a href=#163 id=163 data-nosnippet>163</a>}
<a href=#164 id=164 data-nosnippet>164</a>
<a href=#165 id=165 data-nosnippet>165</a><span class="doccomment">/// Attaches extension metadata and settings to JSON2 columns.
<a href=#166 id=166 data-nosnippet>166</a></span><span class="kw">fn </span>set_json2_extension(column_schema: <span class="kw-2">&amp;mut </span>ColumnSchema, column: <span class="kw-2">&amp;</span>Column) -&gt; <span class="prelude-ty">Result</span>&lt;()&gt; {
<a href=#167 id=167 data-nosnippet>167</a> <span class="kw">if </span>!column_schema.data_type.is_json2() {
<a href=#168 id=168 data-nosnippet>168</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(());
<a href=#169 id=169 data-nosnippet>169</a> }
<a href=#170 id=170 data-nosnippet>170</a>
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">let </span>settings = column
<a href=#172 id=172 data-nosnippet>172</a> .extensions
<a href=#173 id=173 data-nosnippet>173</a> .build_json_settings()<span class="question-mark">?
<a href=#174 id=174 data-nosnippet>174</a> </span>.unwrap_or_else(JsonSettings::new_v2);
<a href=#175 id=175 data-nosnippet>175</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(extension) = json2_extension(column.data_type(), settings) {
<a href=#176 id=176 data-nosnippet>176</a> column_schema.with_extension_type(<span class="kw-2">&amp;</span>extension);
<a href=#177 id=177 data-nosnippet>177</a> }
<a href=#178 id=178 data-nosnippet>178</a>
<a href=#179 id=179 data-nosnippet>179</a> <span class="prelude-val">Ok</span>(())
<a href=#180 id=180 data-nosnippet>180</a>}
<a href=#181 id=181 data-nosnippet>181</a>
<a href=#182 id=182 data-nosnippet>182</a><span class="doccomment">/// Converts a SQL [`Column`] to a `ColumnDef` in gRPC proto.
<a href=#183 id=183 data-nosnippet>183</a></span><span class="kw">pub fn </span>sql_col_to_grpc_col_def(
<a href=#184 id=184 data-nosnippet>184</a> column: <span class="kw-2">&amp;</span>Column,
<a href=#185 id=185 data-nosnippet>185</a> timezone: <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>Timezone&gt;,
<a href=#186 id=186 data-nosnippet>186</a>) -&gt; <span class="prelude-ty">Result</span>&lt;api::v1::ColumnDef&gt; {
<a href=#187 id=187 data-nosnippet>187</a> <span class="kw">let </span>col = <span class="kw-2">&amp;</span>column.column_def;
<a href=#188 id=188 data-nosnippet>188</a> <span class="kw">let </span>name = col.name.value.clone();
<a href=#189 id=189 data-nosnippet>189</a> <span class="kw">let </span>data_type = sql_data_type_to_concrete_data_type(<span class="kw-2">&amp;</span>col.data_type)<span class="question-mark">?</span>;
<a href=#190 id=190 data-nosnippet>190</a>
<a href=#191 id=191 data-nosnippet>191</a> <span class="kw">let </span>is_nullable = col
<a href=#192 id=192 data-nosnippet>192</a> .options
<a href=#193 id=193 data-nosnippet>193</a> .iter()
<a href=#194 id=194 data-nosnippet>194</a> .all(|o| !<span class="macro">matches!</span>(o.option, ColumnOption::NotNull));
<a href=#195 id=195 data-nosnippet>195</a>
<a href=#196 id=196 data-nosnippet>196</a> <span class="kw">let </span>default_constraint =
<a href=#197 id=197 data-nosnippet>197</a> parse_column_default_constraint(<span class="kw-2">&amp;</span>name, <span class="kw-2">&amp;</span>data_type, <span class="kw-2">&amp;</span>col.options, timezone)
<a href=#198 id=198 data-nosnippet>198</a> .context(SqlCommonSnafu)<span class="question-mark">?
<a href=#199 id=199 data-nosnippet>199</a> </span>.map(ColumnDefaultConstraint::try_into) <span class="comment">// serialize default constraint to bytes
<a href=#200 id=200 data-nosnippet>200</a> </span>.transpose()
<a href=#201 id=201 data-nosnippet>201</a> .context(SerializeColumnDefaultConstraintSnafu)<span class="question-mark">?</span>;
<a href=#202 id=202 data-nosnippet>202</a> <span class="comment">// convert ConcreteDataType to grpc ColumnDataTypeWrapper
<a href=#203 id=203 data-nosnippet>203</a> </span><span class="kw">let </span>(datatype, datatype_ext) = ColumnDataTypeWrapper::try_from(data_type.clone())
<a href=#204 id=204 data-nosnippet>204</a> .context(ConvertToGrpcDataTypeSnafu)<span class="question-mark">?
<a href=#205 id=205 data-nosnippet>205</a> </span>.to_parts();
<a href=#206 id=206 data-nosnippet>206</a>
<a href=#207 id=207 data-nosnippet>207</a> <span class="kw">let </span>is_primary_key = col
<a href=#208 id=208 data-nosnippet>208</a> .options
<a href=#209 id=209 data-nosnippet>209</a> .iter()
<a href=#210 id=210 data-nosnippet>210</a> .any(|o| <span class="macro">matches!</span>(o.option, ColumnOption::PrimaryKey(..)));
<a href=#211 id=211 data-nosnippet>211</a>
<a href=#212 id=212 data-nosnippet>212</a> <span class="kw">let </span>semantic_type = <span class="kw">if </span>is_primary_key {
<a href=#213 id=213 data-nosnippet>213</a> SemanticType::Tag
<a href=#214 id=214 data-nosnippet>214</a> } <span class="kw">else </span>{
<a href=#215 id=215 data-nosnippet>215</a> SemanticType::Field
<a href=#216 id=216 data-nosnippet>216</a> };
<a href=#217 id=217 data-nosnippet>217</a>
<a href=#218 id=218 data-nosnippet>218</a> <span class="kw">let </span>settings = column
<a href=#219 id=219 data-nosnippet>219</a> .extensions
<a href=#220 id=220 data-nosnippet>220</a> .build_json_settings()<span class="question-mark">?
<a href=#221 id=221 data-nosnippet>221</a> </span>.unwrap_or_else(JsonSettings::new_v2);
<a href=#222 id=222 data-nosnippet>222</a> <span class="kw">let </span>options = json2_extension(<span class="kw-2">&amp;</span>col.data_type, settings).map(|extension| {
<a href=#223 id=223 data-nosnippet>223</a> <span class="kw">let </span><span class="kw-2">mut </span>options = ColumnOptions::default();
<a href=#224 id=224 data-nosnippet>224</a> options.options.insert(
<a href=#225 id=225 data-nosnippet>225</a> EXTENSION_TYPE_NAME_KEY.to_string(),
<a href=#226 id=226 data-nosnippet>226</a> Json2ExtensionType::NAME.to_string(),
<a href=#227 id=227 data-nosnippet>227</a> );
<a href=#228 id=228 data-nosnippet>228</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(metadata) = extension.serialize_metadata() {
<a href=#229 id=229 data-nosnippet>229</a> options
<a href=#230 id=230 data-nosnippet>230</a> .options
<a href=#231 id=231 data-nosnippet>231</a> .insert(EXTENSION_TYPE_METADATA_KEY.to_string(), metadata);
<a href=#232 id=232 data-nosnippet>232</a> }
<a href=#233 id=233 data-nosnippet>233</a> options
<a href=#234 id=234 data-nosnippet>234</a> });
<a href=#235 id=235 data-nosnippet>235</a>
<a href=#236 id=236 data-nosnippet>236</a> <span class="prelude-val">Ok</span>(api::v1::ColumnDef {
<a href=#237 id=237 data-nosnippet>237</a> name,
<a href=#238 id=238 data-nosnippet>238</a> data_type: datatype <span class="kw">as </span>i32,
<a href=#239 id=239 data-nosnippet>239</a> is_nullable,
<a href=#240 id=240 data-nosnippet>240</a> default_constraint: default_constraint.unwrap_or_default(),
<a href=#241 id=241 data-nosnippet>241</a> semantic_type: semantic_type <span class="kw">as _</span>,
<a href=#242 id=242 data-nosnippet>242</a> comment: String::new(),
<a href=#243 id=243 data-nosnippet>243</a> datatype_extension: datatype_ext,
<a href=#244 id=244 data-nosnippet>244</a> options,
<a href=#245 id=245 data-nosnippet>245</a> })
<a href=#246 id=246 data-nosnippet>246</a>}
<a href=#247 id=247 data-nosnippet>247</a>
<a href=#248 id=248 data-nosnippet>248</a><span class="kw">fn </span>json2_extension(data_type: <span class="kw-2">&amp;</span>SqlDataType, settings: JsonSettings) -&gt; <span class="prelude-ty">Option</span>&lt;Json2ExtensionType&gt; {
<a href=#249 id=249 data-nosnippet>249</a> <span class="kw">let </span>SqlDataType::Custom(name, <span class="kw">_</span>) = data_type <span class="kw">else </span>{
<a href=#250 id=250 data-nosnippet>250</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#251 id=251 data-nosnippet>251</a> };
<a href=#252 id=252 data-nosnippet>252</a> <span class="kw">if </span>!name.<span class="number">0</span>.first().is_some_and(|name| {
<a href=#253 id=253 data-nosnippet>253</a> name.to_string_unquoted()
<a href=#254 id=254 data-nosnippet>254</a> .eq_ignore_ascii_case(JSON2_TYPE_NAME)
<a href=#255 id=255 data-nosnippet>255</a> }) {
<a href=#256 id=256 data-nosnippet>256</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#257 id=257 data-nosnippet>257</a> }
<a href=#258 id=258 data-nosnippet>258</a>
<a href=#259 id=259 data-nosnippet>259</a> <span class="prelude-val">Some</span>(Json2ExtensionType::new(Arc::new(JsonMetadata::new(
<a href=#260 id=260 data-nosnippet>260</a> settings,
<a href=#261 id=261 data-nosnippet>261</a> ))))
<a href=#262 id=262 data-nosnippet>262</a>}
<a href=#263 id=263 data-nosnippet>263</a>
<a href=#264 id=264 data-nosnippet>264</a><span class="kw">pub fn </span>sql_data_type_to_concrete_data_type(data_type: <span class="kw-2">&amp;</span>SqlDataType) -&gt; <span class="prelude-ty">Result</span>&lt;ConcreteDataType&gt; {
<a href=#265 id=265 data-nosnippet>265</a> <span class="kw">match </span>data_type {
<a href=#266 id=266 data-nosnippet>266</a> SqlDataType::BigInt(<span class="kw">_</span>) | SqlDataType::Int64 =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::int64_datatype()),
<a href=#267 id=267 data-nosnippet>267</a> SqlDataType::BigIntUnsigned(<span class="kw">_</span>) | SqlDataType::UInt64 =&gt; {
<a href=#268 id=268 data-nosnippet>268</a> <span class="prelude-val">Ok</span>(ConcreteDataType::uint64_datatype())
<a href=#269 id=269 data-nosnippet>269</a> }
<a href=#270 id=270 data-nosnippet>270</a> SqlDataType::Int(<span class="kw">_</span>) | SqlDataType::Integer(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::int32_datatype()),
<a href=#271 id=271 data-nosnippet>271</a> SqlDataType::IntUnsigned(<span class="kw">_</span>) | SqlDataType::UnsignedInteger =&gt; {
<a href=#272 id=272 data-nosnippet>272</a> <span class="prelude-val">Ok</span>(ConcreteDataType::uint32_datatype())
<a href=#273 id=273 data-nosnippet>273</a> }
<a href=#274 id=274 data-nosnippet>274</a> SqlDataType::SmallInt(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::int16_datatype()),
<a href=#275 id=275 data-nosnippet>275</a> SqlDataType::SmallIntUnsigned(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::uint16_datatype()),
<a href=#276 id=276 data-nosnippet>276</a> SqlDataType::TinyInt(<span class="kw">_</span>) | SqlDataType::Int8(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::int8_datatype()),
<a href=#277 id=277 data-nosnippet>277</a> SqlDataType::TinyIntUnsigned(<span class="kw">_</span>) | SqlDataType::Int8Unsigned(<span class="kw">_</span>) =&gt; {
<a href=#278 id=278 data-nosnippet>278</a> <span class="prelude-val">Ok</span>(ConcreteDataType::uint8_datatype())
<a href=#279 id=279 data-nosnippet>279</a> }
<a href=#280 id=280 data-nosnippet>280</a> SqlDataType::Char(<span class="kw">_</span>)
<a href=#281 id=281 data-nosnippet>281</a> | SqlDataType::Varchar(<span class="kw">_</span>)
<a href=#282 id=282 data-nosnippet>282</a> | SqlDataType::Text
<a href=#283 id=283 data-nosnippet>283</a> | SqlDataType::TinyText
<a href=#284 id=284 data-nosnippet>284</a> | SqlDataType::MediumText
<a href=#285 id=285 data-nosnippet>285</a> | SqlDataType::LongText
<a href=#286 id=286 data-nosnippet>286</a> | SqlDataType::String(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::string_datatype()),
<a href=#287 id=287 data-nosnippet>287</a> SqlDataType::Float(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::float32_datatype()),
<a href=#288 id=288 data-nosnippet>288</a> SqlDataType::Double(<span class="kw">_</span>) | SqlDataType::Float64 =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::float64_datatype()),
<a href=#289 id=289 data-nosnippet>289</a> SqlDataType::Boolean =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::boolean_datatype()),
<a href=#290 id=290 data-nosnippet>290</a> SqlDataType::Date =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::date_datatype()),
<a href=#291 id=291 data-nosnippet>291</a> SqlDataType::Binary(<span class="kw">_</span>)
<a href=#292 id=292 data-nosnippet>292</a> | SqlDataType::Blob(<span class="kw">_</span>)
<a href=#293 id=293 data-nosnippet>293</a> | SqlDataType::Bytea
<a href=#294 id=294 data-nosnippet>294</a> | SqlDataType::Varbinary(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::binary_datatype()),
<a href=#295 id=295 data-nosnippet>295</a> SqlDataType::Datetime(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::timestamp_microsecond_datatype()),
<a href=#296 id=296 data-nosnippet>296</a> SqlDataType::Timestamp(precision, <span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(precision
<a href=#297 id=297 data-nosnippet>297</a> .as_ref()
<a href=#298 id=298 data-nosnippet>298</a> .map(|v| TimestampType::try_from(<span class="kw-2">*</span>v))
<a href=#299 id=299 data-nosnippet>299</a> .transpose()
<a href=#300 id=300 data-nosnippet>300</a> .map_err(|<span class="kw">_</span>| {
<a href=#301 id=301 data-nosnippet>301</a> error::SqlTypeNotSupportedSnafu {
<a href=#302 id=302 data-nosnippet>302</a> t: data_type.clone(),
<a href=#303 id=303 data-nosnippet>303</a> }
<a href=#304 id=304 data-nosnippet>304</a> .build()
<a href=#305 id=305 data-nosnippet>305</a> })<span class="question-mark">?
<a href=#306 id=306 data-nosnippet>306</a> </span>.map(|t| ConcreteDataType::timestamp_datatype(t.unit()))
<a href=#307 id=307 data-nosnippet>307</a> .unwrap_or(ConcreteDataType::timestamp_millisecond_datatype())),
<a href=#308 id=308 data-nosnippet>308</a> SqlDataType::Interval { .. } =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::interval_month_day_nano_datatype()),
<a href=#309 id=309 data-nosnippet>309</a> SqlDataType::Decimal(exact_info) =&gt; <span class="kw">match </span>exact_info {
<a href=#310 id=310 data-nosnippet>310</a> ExactNumberInfo::None =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::decimal128_default_datatype()),
<a href=#311 id=311 data-nosnippet>311</a> <span class="comment">// refer to https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html
<a href=#312 id=312 data-nosnippet>312</a> // In standard SQL, the syntax DECIMAL(M) is equivalent to DECIMAL(M,0).
<a href=#313 id=313 data-nosnippet>313</a> </span>ExactNumberInfo::Precision(p) =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::decimal128_datatype(<span class="kw-2">*</span>p <span class="kw">as </span>u8, <span class="number">0</span>)),
<a href=#314 id=314 data-nosnippet>314</a> ExactNumberInfo::PrecisionAndScale(p, s) =&gt; {
<a href=#315 id=315 data-nosnippet>315</a> <span class="prelude-val">Ok</span>(ConcreteDataType::decimal128_datatype(<span class="kw-2">*</span>p <span class="kw">as </span>u8, <span class="kw-2">*</span>s <span class="kw">as </span>i8))
<a href=#316 id=316 data-nosnippet>316</a> }
<a href=#317 id=317 data-nosnippet>317</a> },
<a href=#318 id=318 data-nosnippet>318</a> SqlDataType::JSON =&gt; <span class="prelude-val">Ok</span>(ConcreteDataType::Json(JsonType::new(JsonFormat::Jsonb))),
<a href=#319 id=319 data-nosnippet>319</a> <span class="comment">// Vector type and JSON2 type
<a href=#320 id=320 data-nosnippet>320</a> </span>SqlDataType::Custom(name, args) <span class="kw">if </span>name.<span class="number">0</span>.len() == <span class="number">1 </span>=&gt; {
<a href=#321 id=321 data-nosnippet>321</a> <span class="kw">let </span>name = name.<span class="number">0</span>[<span class="number">0</span>].to_string_unquoted().to_ascii_uppercase();
<a href=#322 id=322 data-nosnippet>322</a> <span class="kw">match </span>name.as_str() {
<a href=#323 id=323 data-nosnippet>323</a> VECTOR_TYPE_NAME <span class="kw">if </span>args.len() == <span class="number">1 </span>=&gt; {
<a href=#324 id=324 data-nosnippet>324</a> <span class="kw">let </span>dim = <span class="kw-2">&amp;</span>args[<span class="number">0</span>];
<a href=#325 id=325 data-nosnippet>325</a> <span class="kw">let </span>dim = dim.parse().map_err(|e| {
<a href=#326 id=326 data-nosnippet>326</a> error::ParseSqlValueSnafu {
<a href=#327 id=327 data-nosnippet>327</a> msg: <span class="macro">format!</span>(<span class="string">"Failed to parse vector dimension '{}': {}"</span>, dim, e),
<a href=#328 id=328 data-nosnippet>328</a> }
<a href=#329 id=329 data-nosnippet>329</a> .build()
<a href=#330 id=330 data-nosnippet>330</a> })<span class="question-mark">?</span>;
<a href=#331 id=331 data-nosnippet>331</a> <span class="prelude-val">Ok</span>(ConcreteDataType::vector_datatype(dim))
<a href=#332 id=332 data-nosnippet>332</a> }
<a href=#333 id=333 data-nosnippet>333</a> JSON2_TYPE_NAME <span class="kw">if </span>args.is_empty() =&gt; {
<a href=#334 id=334 data-nosnippet>334</a> <span class="comment">// Currently, JSON2 is not inferred as any native type initially.
<a href=#335 id=335 data-nosnippet>335</a> // TODO(fys): infer it later from type hints.
<a href=#336 id=336 data-nosnippet>336</a> </span><span class="kw">let </span>format = JsonFormat::Json2(Arc::new(JsonNativeType::Null));
<a href=#337 id=337 data-nosnippet>337</a> <span class="prelude-val">Ok</span>(ConcreteDataType::Json(JsonType::new(format)))
<a href=#338 id=338 data-nosnippet>338</a> }
<a href=#339 id=339 data-nosnippet>339</a> <span class="kw">_ </span>=&gt; error::SqlTypeNotSupportedSnafu {
<a href=#340 id=340 data-nosnippet>340</a> t: data_type.clone(),
<a href=#341 id=341 data-nosnippet>341</a> }
<a href=#342 id=342 data-nosnippet>342</a> .fail(),
<a href=#343 id=343 data-nosnippet>343</a> }
<a href=#344 id=344 data-nosnippet>344</a> }
<a href=#345 id=345 data-nosnippet>345</a> <span class="kw">_ </span>=&gt; error::SqlTypeNotSupportedSnafu {
<a href=#346 id=346 data-nosnippet>346</a> t: data_type.clone(),
<a href=#347 id=347 data-nosnippet>347</a> }
<a href=#348 id=348 data-nosnippet>348</a> .fail(),
<a href=#349 id=349 data-nosnippet>349</a> }
<a href=#350 id=350 data-nosnippet>350</a>}
<a href=#351 id=351 data-nosnippet>351</a>
<a href=#352 id=352 data-nosnippet>352</a><span class="kw">pub fn </span>concrete_data_type_to_sql_data_type(data_type: <span class="kw-2">&amp;</span>ConcreteDataType) -&gt; <span class="prelude-ty">Result</span>&lt;SqlDataType&gt; {
<a href=#353 id=353 data-nosnippet>353</a> <span class="kw">match </span>data_type {
<a href=#354 id=354 data-nosnippet>354</a> ConcreteDataType::Int64(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::BigInt(<span class="prelude-val">None</span>)),
<a href=#355 id=355 data-nosnippet>355</a> ConcreteDataType::UInt64(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::BigIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#356 id=356 data-nosnippet>356</a> ConcreteDataType::Int32(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Int(<span class="prelude-val">None</span>)),
<a href=#357 id=357 data-nosnippet>357</a> ConcreteDataType::UInt32(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::IntUnsigned(<span class="prelude-val">None</span>)),
<a href=#358 id=358 data-nosnippet>358</a> ConcreteDataType::Int16(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::SmallInt(<span class="prelude-val">None</span>)),
<a href=#359 id=359 data-nosnippet>359</a> ConcreteDataType::UInt16(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::SmallIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#360 id=360 data-nosnippet>360</a> ConcreteDataType::Int8(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::TinyInt(<span class="prelude-val">None</span>)),
<a href=#361 id=361 data-nosnippet>361</a> ConcreteDataType::UInt8(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::TinyIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#362 id=362 data-nosnippet>362</a> ConcreteDataType::String(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::String(<span class="prelude-val">None</span>)),
<a href=#363 id=363 data-nosnippet>363</a> ConcreteDataType::Float32(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Float(ExactNumberInfo::None)),
<a href=#364 id=364 data-nosnippet>364</a> ConcreteDataType::Float64(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Double(ExactNumberInfo::None)),
<a href=#365 id=365 data-nosnippet>365</a> ConcreteDataType::Boolean(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Boolean),
<a href=#366 id=366 data-nosnippet>366</a> ConcreteDataType::Date(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Date),
<a href=#367 id=367 data-nosnippet>367</a> ConcreteDataType::Timestamp(ts_type) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Timestamp(
<a href=#368 id=368 data-nosnippet>368</a> <span class="prelude-val">Some</span>(ts_type.precision()),
<a href=#369 id=369 data-nosnippet>369</a> TimezoneInfo::None,
<a href=#370 id=370 data-nosnippet>370</a> )),
<a href=#371 id=371 data-nosnippet>371</a> ConcreteDataType::Time(time_type) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Time(
<a href=#372 id=372 data-nosnippet>372</a> <span class="prelude-val">Some</span>(time_type.precision()),
<a href=#373 id=373 data-nosnippet>373</a> TimezoneInfo::None,
<a href=#374 id=374 data-nosnippet>374</a> )),
<a href=#375 id=375 data-nosnippet>375</a> ConcreteDataType::Interval(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Interval {
<a href=#376 id=376 data-nosnippet>376</a> fields: <span class="prelude-val">None</span>,
<a href=#377 id=377 data-nosnippet>377</a> precision: <span class="prelude-val">None</span>,
<a href=#378 id=378 data-nosnippet>378</a> }),
<a href=#379 id=379 data-nosnippet>379</a> ConcreteDataType::Binary(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Varbinary(<span class="prelude-val">None</span>)),
<a href=#380 id=380 data-nosnippet>380</a> ConcreteDataType::Decimal128(d) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Decimal(
<a href=#381 id=381 data-nosnippet>381</a> ExactNumberInfo::PrecisionAndScale(d.precision() <span class="kw">as </span>u64, d.scale() <span class="kw">as </span>i64),
<a href=#382 id=382 data-nosnippet>382</a> )),
<a href=#383 id=383 data-nosnippet>383</a> ConcreteDataType::Json(<span class="kw">_</span>) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::JSON),
<a href=#384 id=384 data-nosnippet>384</a> ConcreteDataType::Vector(v) =&gt; <span class="prelude-val">Ok</span>(SqlDataType::Custom(
<a href=#385 id=385 data-nosnippet>385</a> <span class="macro">vec!</span>[Ident::new(VECTOR_TYPE_NAME)].into(),
<a href=#386 id=386 data-nosnippet>386</a> <span class="macro">vec!</span>[v.dim.to_string()],
<a href=#387 id=387 data-nosnippet>387</a> )),
<a href=#388 id=388 data-nosnippet>388</a> ConcreteDataType::Duration(<span class="kw">_</span>)
<a href=#389 id=389 data-nosnippet>389</a> | ConcreteDataType::Null(<span class="kw">_</span>)
<a href=#390 id=390 data-nosnippet>390</a> | ConcreteDataType::List(<span class="kw">_</span>)
<a href=#391 id=391 data-nosnippet>391</a> | ConcreteDataType::Struct(<span class="kw">_</span>)
<a href=#392 id=392 data-nosnippet>392</a> | ConcreteDataType::Dictionary(<span class="kw">_</span>) =&gt; error::ConcreteTypeNotSupportedSnafu {
<a href=#393 id=393 data-nosnippet>393</a> t: data_type.clone(),
<a href=#394 id=394 data-nosnippet>394</a> }
<a href=#395 id=395 data-nosnippet>395</a> .fail(),
<a href=#396 id=396 data-nosnippet>396</a> }
<a href=#397 id=397 data-nosnippet>397</a>}
<a href=#398 id=398 data-nosnippet>398</a>
<a href=#399 id=399 data-nosnippet>399</a><span class="attr">#[cfg(test)]
<a href=#400 id=400 data-nosnippet>400</a></span><span class="kw">mod </span>tests {
<a href=#401 id=401 data-nosnippet>401</a> <span class="kw">use </span>api::v1::ColumnDataType;
<a href=#402 id=402 data-nosnippet>402</a> <span class="kw">use </span>datatypes::schema::{
<a href=#403 id=403 data-nosnippet>403</a> COLUMN_FULLTEXT_OPT_KEY_ANALYZER, COLUMN_FULLTEXT_OPT_KEY_CASE_SENSITIVE, FulltextAnalyzer,
<a href=#404 id=404 data-nosnippet>404</a> };
<a href=#405 id=405 data-nosnippet>405</a> <span class="kw">use </span>sqlparser::ast::{ColumnOptionDef, Expr, PrimaryKeyConstraint};
<a href=#406 id=406 data-nosnippet>406</a>
<a href=#407 id=407 data-nosnippet>407</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#408 id=408 data-nosnippet>408</a> <span class="kw">use </span><span class="kw">crate</span>::ast::TimezoneInfo;
<a href=#409 id=409 data-nosnippet>409</a> <span class="kw">use </span><span class="kw">crate</span>::statements::ColumnOption;
<a href=#410 id=410 data-nosnippet>410</a> <span class="kw">use </span><span class="kw">crate</span>::statements::create::ColumnExtensions;
<a href=#411 id=411 data-nosnippet>411</a>
<a href=#412 id=412 data-nosnippet>412</a> <span class="kw">fn </span>check_type(sql_type: SqlDataType, data_type: ConcreteDataType) {
<a href=#413 id=413 data-nosnippet>413</a> <span class="macro">assert_eq!</span>(
<a href=#414 id=414 data-nosnippet>414</a> data_type,
<a href=#415 id=415 data-nosnippet>415</a> sql_data_type_to_concrete_data_type(<span class="kw-2">&amp;</span>sql_type).unwrap()
<a href=#416 id=416 data-nosnippet>416</a> );
<a href=#417 id=417 data-nosnippet>417</a> }
<a href=#418 id=418 data-nosnippet>418</a>
<a href=#419 id=419 data-nosnippet>419</a> <span class="attr">#[test]
<a href=#420 id=420 data-nosnippet>420</a> </span><span class="kw">pub fn </span>test_sql_data_type_to_concrete_data_type() {
<a href=#421 id=421 data-nosnippet>421</a> check_type(
<a href=#422 id=422 data-nosnippet>422</a> SqlDataType::BigInt(<span class="prelude-val">None</span>),
<a href=#423 id=423 data-nosnippet>423</a> ConcreteDataType::int64_datatype(),
<a href=#424 id=424 data-nosnippet>424</a> );
<a href=#425 id=425 data-nosnippet>425</a> check_type(SqlDataType::Int(<span class="prelude-val">None</span>), ConcreteDataType::int32_datatype());
<a href=#426 id=426 data-nosnippet>426</a> check_type(
<a href=#427 id=427 data-nosnippet>427</a> SqlDataType::Integer(<span class="prelude-val">None</span>),
<a href=#428 id=428 data-nosnippet>428</a> ConcreteDataType::int32_datatype(),
<a href=#429 id=429 data-nosnippet>429</a> );
<a href=#430 id=430 data-nosnippet>430</a> check_type(
<a href=#431 id=431 data-nosnippet>431</a> SqlDataType::SmallInt(<span class="prelude-val">None</span>),
<a href=#432 id=432 data-nosnippet>432</a> ConcreteDataType::int16_datatype(),
<a href=#433 id=433 data-nosnippet>433</a> );
<a href=#434 id=434 data-nosnippet>434</a> check_type(SqlDataType::Char(<span class="prelude-val">None</span>), ConcreteDataType::string_datatype());
<a href=#435 id=435 data-nosnippet>435</a> check_type(
<a href=#436 id=436 data-nosnippet>436</a> SqlDataType::Varchar(<span class="prelude-val">None</span>),
<a href=#437 id=437 data-nosnippet>437</a> ConcreteDataType::string_datatype(),
<a href=#438 id=438 data-nosnippet>438</a> );
<a href=#439 id=439 data-nosnippet>439</a> check_type(SqlDataType::Text, ConcreteDataType::string_datatype());
<a href=#440 id=440 data-nosnippet>440</a> check_type(
<a href=#441 id=441 data-nosnippet>441</a> SqlDataType::String(<span class="prelude-val">None</span>),
<a href=#442 id=442 data-nosnippet>442</a> ConcreteDataType::string_datatype(),
<a href=#443 id=443 data-nosnippet>443</a> );
<a href=#444 id=444 data-nosnippet>444</a> check_type(
<a href=#445 id=445 data-nosnippet>445</a> SqlDataType::Float(ExactNumberInfo::None),
<a href=#446 id=446 data-nosnippet>446</a> ConcreteDataType::float32_datatype(),
<a href=#447 id=447 data-nosnippet>447</a> );
<a href=#448 id=448 data-nosnippet>448</a> check_type(
<a href=#449 id=449 data-nosnippet>449</a> SqlDataType::Double(ExactNumberInfo::None),
<a href=#450 id=450 data-nosnippet>450</a> ConcreteDataType::float64_datatype(),
<a href=#451 id=451 data-nosnippet>451</a> );
<a href=#452 id=452 data-nosnippet>452</a> check_type(SqlDataType::Boolean, ConcreteDataType::boolean_datatype());
<a href=#453 id=453 data-nosnippet>453</a> check_type(SqlDataType::Date, ConcreteDataType::date_datatype());
<a href=#454 id=454 data-nosnippet>454</a> check_type(
<a href=#455 id=455 data-nosnippet>455</a> SqlDataType::Timestamp(<span class="prelude-val">None</span>, TimezoneInfo::None),
<a href=#456 id=456 data-nosnippet>456</a> ConcreteDataType::timestamp_millisecond_datatype(),
<a href=#457 id=457 data-nosnippet>457</a> );
<a href=#458 id=458 data-nosnippet>458</a> check_type(
<a href=#459 id=459 data-nosnippet>459</a> SqlDataType::Varbinary(<span class="prelude-val">None</span>),
<a href=#460 id=460 data-nosnippet>460</a> ConcreteDataType::binary_datatype(),
<a href=#461 id=461 data-nosnippet>461</a> );
<a href=#462 id=462 data-nosnippet>462</a> check_type(
<a href=#463 id=463 data-nosnippet>463</a> SqlDataType::BigIntUnsigned(<span class="prelude-val">None</span>),
<a href=#464 id=464 data-nosnippet>464</a> ConcreteDataType::uint64_datatype(),
<a href=#465 id=465 data-nosnippet>465</a> );
<a href=#466 id=466 data-nosnippet>466</a> check_type(SqlDataType::UInt64, ConcreteDataType::uint64_datatype());
<a href=#467 id=467 data-nosnippet>467</a> check_type(
<a href=#468 id=468 data-nosnippet>468</a> SqlDataType::IntUnsigned(<span class="prelude-val">None</span>),
<a href=#469 id=469 data-nosnippet>469</a> ConcreteDataType::uint32_datatype(),
<a href=#470 id=470 data-nosnippet>470</a> );
<a href=#471 id=471 data-nosnippet>471</a> check_type(
<a href=#472 id=472 data-nosnippet>472</a> SqlDataType::SmallIntUnsigned(<span class="prelude-val">None</span>),
<a href=#473 id=473 data-nosnippet>473</a> ConcreteDataType::uint16_datatype(),
<a href=#474 id=474 data-nosnippet>474</a> );
<a href=#475 id=475 data-nosnippet>475</a> check_type(
<a href=#476 id=476 data-nosnippet>476</a> SqlDataType::TinyIntUnsigned(<span class="prelude-val">None</span>),
<a href=#477 id=477 data-nosnippet>477</a> ConcreteDataType::uint8_datatype(),
<a href=#478 id=478 data-nosnippet>478</a> );
<a href=#479 id=479 data-nosnippet>479</a> check_type(
<a href=#480 id=480 data-nosnippet>480</a> SqlDataType::Datetime(<span class="prelude-val">None</span>),
<a href=#481 id=481 data-nosnippet>481</a> ConcreteDataType::timestamp_microsecond_datatype(),
<a href=#482 id=482 data-nosnippet>482</a> );
<a href=#483 id=483 data-nosnippet>483</a> check_type(
<a href=#484 id=484 data-nosnippet>484</a> SqlDataType::Interval {
<a href=#485 id=485 data-nosnippet>485</a> fields: <span class="prelude-val">None</span>,
<a href=#486 id=486 data-nosnippet>486</a> precision: <span class="prelude-val">None</span>,
<a href=#487 id=487 data-nosnippet>487</a> },
<a href=#488 id=488 data-nosnippet>488</a> ConcreteDataType::interval_month_day_nano_datatype(),
<a href=#489 id=489 data-nosnippet>489</a> );
<a href=#490 id=490 data-nosnippet>490</a> check_type(SqlDataType::JSON, ConcreteDataType::json_datatype());
<a href=#491 id=491 data-nosnippet>491</a> check_type(
<a href=#492 id=492 data-nosnippet>492</a> SqlDataType::Custom(
<a href=#493 id=493 data-nosnippet>493</a> <span class="macro">vec!</span>[Ident::new(VECTOR_TYPE_NAME)].into(),
<a href=#494 id=494 data-nosnippet>494</a> <span class="macro">vec!</span>[<span class="string">"3"</span>.to_string()],
<a href=#495 id=495 data-nosnippet>495</a> ),
<a href=#496 id=496 data-nosnippet>496</a> ConcreteDataType::vector_datatype(<span class="number">3</span>),
<a href=#497 id=497 data-nosnippet>497</a> );
<a href=#498 id=498 data-nosnippet>498</a> }
<a href=#499 id=499 data-nosnippet>499</a>
<a href=#500 id=500 data-nosnippet>500</a> <span class="attr">#[test]
<a href=#501 id=501 data-nosnippet>501</a> </span><span class="kw">pub fn </span>test_sql_col_to_grpc_col_def() {
<a href=#502 id=502 data-nosnippet>502</a> <span class="comment">// test basic
<a href=#503 id=503 data-nosnippet>503</a> </span><span class="kw">let </span>column = Column {
<a href=#504 id=504 data-nosnippet>504</a> column_def: ColumnDef {
<a href=#505 id=505 data-nosnippet>505</a> name: <span class="string">"col"</span>.into(),
<a href=#506 id=506 data-nosnippet>506</a> data_type: SqlDataType::Double(ExactNumberInfo::None),
<a href=#507 id=507 data-nosnippet>507</a> options: <span class="macro">vec!</span>[],
<a href=#508 id=508 data-nosnippet>508</a> },
<a href=#509 id=509 data-nosnippet>509</a> extensions: ColumnExtensions::default(),
<a href=#510 id=510 data-nosnippet>510</a> };
<a href=#511 id=511 data-nosnippet>511</a>
<a href=#512 id=512 data-nosnippet>512</a> <span class="kw">let </span>grpc_column_def = sql_col_to_grpc_col_def(<span class="kw-2">&amp;</span>column, <span class="prelude-val">None</span>).unwrap();
<a href=#513 id=513 data-nosnippet>513</a>
<a href=#514 id=514 data-nosnippet>514</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, grpc_column_def.name);
<a href=#515 id=515 data-nosnippet>515</a> <span class="macro">assert!</span>(grpc_column_def.is_nullable); <span class="comment">// nullable when options are empty
<a href=#516 id=516 data-nosnippet>516</a> </span><span class="macro">assert_eq!</span>(ColumnDataType::Float64 <span class="kw">as </span>i32, grpc_column_def.data_type);
<a href=#517 id=517 data-nosnippet>517</a> <span class="macro">assert!</span>(grpc_column_def.default_constraint.is_empty());
<a href=#518 id=518 data-nosnippet>518</a> <span class="macro">assert_eq!</span>(grpc_column_def.semantic_type, SemanticType::Field <span class="kw">as </span>i32);
<a href=#519 id=519 data-nosnippet>519</a>
<a href=#520 id=520 data-nosnippet>520</a> <span class="comment">// test not null
<a href=#521 id=521 data-nosnippet>521</a> </span><span class="kw">let </span>column = Column {
<a href=#522 id=522 data-nosnippet>522</a> column_def: ColumnDef {
<a href=#523 id=523 data-nosnippet>523</a> name: <span class="string">"col"</span>.into(),
<a href=#524 id=524 data-nosnippet>524</a> data_type: SqlDataType::Double(ExactNumberInfo::None),
<a href=#525 id=525 data-nosnippet>525</a> options: <span class="macro">vec!</span>[ColumnOptionDef {
<a href=#526 id=526 data-nosnippet>526</a> name: <span class="prelude-val">None</span>,
<a href=#527 id=527 data-nosnippet>527</a> option: ColumnOption::NotNull,
<a href=#528 id=528 data-nosnippet>528</a> }],
<a href=#529 id=529 data-nosnippet>529</a> },
<a href=#530 id=530 data-nosnippet>530</a> extensions: ColumnExtensions::default(),
<a href=#531 id=531 data-nosnippet>531</a> };
<a href=#532 id=532 data-nosnippet>532</a>
<a href=#533 id=533 data-nosnippet>533</a> <span class="kw">let </span>grpc_column_def = sql_col_to_grpc_col_def(<span class="kw-2">&amp;</span>column, <span class="prelude-val">None</span>).unwrap();
<a href=#534 id=534 data-nosnippet>534</a> <span class="macro">assert!</span>(!grpc_column_def.is_nullable);
<a href=#535 id=535 data-nosnippet>535</a>
<a href=#536 id=536 data-nosnippet>536</a> <span class="comment">// test primary key
<a href=#537 id=537 data-nosnippet>537</a> </span><span class="kw">let </span>column = Column {
<a href=#538 id=538 data-nosnippet>538</a> column_def: ColumnDef {
<a href=#539 id=539 data-nosnippet>539</a> name: <span class="string">"col"</span>.into(),
<a href=#540 id=540 data-nosnippet>540</a> data_type: SqlDataType::Double(ExactNumberInfo::None),
<a href=#541 id=541 data-nosnippet>541</a> options: <span class="macro">vec!</span>[ColumnOptionDef {
<a href=#542 id=542 data-nosnippet>542</a> name: <span class="prelude-val">None</span>,
<a href=#543 id=543 data-nosnippet>543</a> option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
<a href=#544 id=544 data-nosnippet>544</a> name: <span class="prelude-val">None</span>,
<a href=#545 id=545 data-nosnippet>545</a> index_name: <span class="prelude-val">None</span>,
<a href=#546 id=546 data-nosnippet>546</a> index_type: <span class="prelude-val">None</span>,
<a href=#547 id=547 data-nosnippet>547</a> columns: <span class="macro">vec!</span>[],
<a href=#548 id=548 data-nosnippet>548</a> index_options: <span class="macro">vec!</span>[],
<a href=#549 id=549 data-nosnippet>549</a> characteristics: <span class="prelude-val">None</span>,
<a href=#550 id=550 data-nosnippet>550</a> }),
<a href=#551 id=551 data-nosnippet>551</a> }],
<a href=#552 id=552 data-nosnippet>552</a> },
<a href=#553 id=553 data-nosnippet>553</a> extensions: ColumnExtensions::default(),
<a href=#554 id=554 data-nosnippet>554</a> };
<a href=#555 id=555 data-nosnippet>555</a>
<a href=#556 id=556 data-nosnippet>556</a> <span class="kw">let </span>grpc_column_def = sql_col_to_grpc_col_def(<span class="kw-2">&amp;</span>column, <span class="prelude-val">None</span>).unwrap();
<a href=#557 id=557 data-nosnippet>557</a> <span class="macro">assert_eq!</span>(grpc_column_def.semantic_type, SemanticType::Tag <span class="kw">as </span>i32);
<a href=#558 id=558 data-nosnippet>558</a> }
<a href=#559 id=559 data-nosnippet>559</a>
<a href=#560 id=560 data-nosnippet>560</a> <span class="attr">#[test]
<a href=#561 id=561 data-nosnippet>561</a> </span><span class="kw">pub fn </span>test_sql_col_to_grpc_col_def_with_timezone() {
<a href=#562 id=562 data-nosnippet>562</a> <span class="kw">let </span>column = Column {
<a href=#563 id=563 data-nosnippet>563</a> column_def: ColumnDef {
<a href=#564 id=564 data-nosnippet>564</a> name: <span class="string">"col"</span>.into(),
<a href=#565 id=565 data-nosnippet>565</a> <span class="comment">// MILLISECOND
<a href=#566 id=566 data-nosnippet>566</a> </span>data_type: SqlDataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">3</span>), TimezoneInfo::None),
<a href=#567 id=567 data-nosnippet>567</a> options: <span class="macro">vec!</span>[ColumnOptionDef {
<a href=#568 id=568 data-nosnippet>568</a> name: <span class="prelude-val">None</span>,
<a href=#569 id=569 data-nosnippet>569</a> option: ColumnOption::Default(Expr::Value(
<a href=#570 id=570 data-nosnippet>570</a> SqlValue::SingleQuotedString(<span class="string">"2024-01-30T00:01:01"</span>.to_string()).into(),
<a href=#571 id=571 data-nosnippet>571</a> )),
<a href=#572 id=572 data-nosnippet>572</a> }],
<a href=#573 id=573 data-nosnippet>573</a> },
<a href=#574 id=574 data-nosnippet>574</a> extensions: ColumnExtensions::default(),
<a href=#575 id=575 data-nosnippet>575</a> };
<a href=#576 id=576 data-nosnippet>576</a>
<a href=#577 id=577 data-nosnippet>577</a> <span class="comment">// with timezone "Asia/Shanghai"
<a href=#578 id=578 data-nosnippet>578</a> </span><span class="kw">let </span>grpc_column_def = sql_col_to_grpc_col_def(
<a href=#579 id=579 data-nosnippet>579</a> <span class="kw-2">&amp;</span>column,
<a href=#580 id=580 data-nosnippet>580</a> <span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>Timezone::from_tz_string(<span class="string">"Asia/Shanghai"</span>).unwrap()),
<a href=#581 id=581 data-nosnippet>581</a> )
<a href=#582 id=582 data-nosnippet>582</a> .unwrap();
<a href=#583 id=583 data-nosnippet>583</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, grpc_column_def.name);
<a href=#584 id=584 data-nosnippet>584</a> <span class="macro">assert!</span>(grpc_column_def.is_nullable); <span class="comment">// nullable when options are empty
<a href=#585 id=585 data-nosnippet>585</a> </span><span class="macro">assert_eq!</span>(
<a href=#586 id=586 data-nosnippet>586</a> ColumnDataType::TimestampMillisecond <span class="kw">as </span>i32,
<a href=#587 id=587 data-nosnippet>587</a> grpc_column_def.data_type
<a href=#588 id=588 data-nosnippet>588</a> );
<a href=#589 id=589 data-nosnippet>589</a> <span class="macro">assert!</span>(!grpc_column_def.default_constraint.is_empty());
<a href=#590 id=590 data-nosnippet>590</a>
<a href=#591 id=591 data-nosnippet>591</a> <span class="kw">let </span>constraint =
<a href=#592 id=592 data-nosnippet>592</a> ColumnDefaultConstraint::try_from(<span class="kw-2">&amp;</span>grpc_column_def.default_constraint[..]).unwrap();
<a href=#593 id=593 data-nosnippet>593</a> <span class="macro">assert!</span>(
<a href=#594 id=594 data-nosnippet>594</a> <span class="macro">matches!</span>(constraint, ColumnDefaultConstraint::Value(Value::Timestamp(ts))
<a href=#595 id=595 data-nosnippet>595</a> <span class="kw">if </span>ts.to_iso8601_string() == <span class="string">"2024-01-29 16:01:01+0000"</span>)
<a href=#596 id=596 data-nosnippet>596</a> );
<a href=#597 id=597 data-nosnippet>597</a>
<a href=#598 id=598 data-nosnippet>598</a> <span class="comment">// without timezone
<a href=#599 id=599 data-nosnippet>599</a> </span><span class="kw">let </span>grpc_column_def = sql_col_to_grpc_col_def(<span class="kw-2">&amp;</span>column, <span class="prelude-val">None</span>).unwrap();
<a href=#600 id=600 data-nosnippet>600</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, grpc_column_def.name);
<a href=#601 id=601 data-nosnippet>601</a> <span class="macro">assert!</span>(grpc_column_def.is_nullable); <span class="comment">// nullable when options are empty
<a href=#602 id=602 data-nosnippet>602</a> </span><span class="macro">assert_eq!</span>(
<a href=#603 id=603 data-nosnippet>603</a> ColumnDataType::TimestampMillisecond <span class="kw">as </span>i32,
<a href=#604 id=604 data-nosnippet>604</a> grpc_column_def.data_type
<a href=#605 id=605 data-nosnippet>605</a> );
<a href=#606 id=606 data-nosnippet>606</a> <span class="macro">assert!</span>(!grpc_column_def.default_constraint.is_empty());
<a href=#607 id=607 data-nosnippet>607</a>
<a href=#608 id=608 data-nosnippet>608</a> <span class="kw">let </span>constraint =
<a href=#609 id=609 data-nosnippet>609</a> ColumnDefaultConstraint::try_from(<span class="kw-2">&amp;</span>grpc_column_def.default_constraint[..]).unwrap();
<a href=#610 id=610 data-nosnippet>610</a> <span class="macro">assert!</span>(
<a href=#611 id=611 data-nosnippet>611</a> <span class="macro">matches!</span>(constraint, ColumnDefaultConstraint::Value(Value::Timestamp(ts))
<a href=#612 id=612 data-nosnippet>612</a> <span class="kw">if </span>ts.to_iso8601_string() == <span class="string">"2024-01-30 00:01:01+0000"</span>)
<a href=#613 id=613 data-nosnippet>613</a> );
<a href=#614 id=614 data-nosnippet>614</a> }
<a href=#615 id=615 data-nosnippet>615</a>
<a href=#616 id=616 data-nosnippet>616</a> <span class="attr">#[test]
<a href=#617 id=617 data-nosnippet>617</a> </span><span class="kw">pub fn </span>test_has_primary_key_option() {
<a href=#618 id=618 data-nosnippet>618</a> <span class="kw">let </span>column_def = ColumnDef {
<a href=#619 id=619 data-nosnippet>619</a> name: <span class="string">"col"</span>.into(),
<a href=#620 id=620 data-nosnippet>620</a> data_type: SqlDataType::Double(ExactNumberInfo::None),
<a href=#621 id=621 data-nosnippet>621</a> options: <span class="macro">vec!</span>[],
<a href=#622 id=622 data-nosnippet>622</a> };
<a href=#623 id=623 data-nosnippet>623</a> <span class="macro">assert!</span>(!has_primary_key_option(<span class="kw-2">&amp;</span>column_def));
<a href=#624 id=624 data-nosnippet>624</a>
<a href=#625 id=625 data-nosnippet>625</a> <span class="kw">let </span>column_def = ColumnDef {
<a href=#626 id=626 data-nosnippet>626</a> name: <span class="string">"col"</span>.into(),
<a href=#627 id=627 data-nosnippet>627</a> data_type: SqlDataType::Double(ExactNumberInfo::None),
<a href=#628 id=628 data-nosnippet>628</a> options: <span class="macro">vec!</span>[ColumnOptionDef {
<a href=#629 id=629 data-nosnippet>629</a> name: <span class="prelude-val">None</span>,
<a href=#630 id=630 data-nosnippet>630</a> option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
<a href=#631 id=631 data-nosnippet>631</a> name: <span class="prelude-val">None</span>,
<a href=#632 id=632 data-nosnippet>632</a> index_name: <span class="prelude-val">None</span>,
<a href=#633 id=633 data-nosnippet>633</a> index_type: <span class="prelude-val">None</span>,
<a href=#634 id=634 data-nosnippet>634</a> columns: <span class="macro">vec!</span>[],
<a href=#635 id=635 data-nosnippet>635</a> index_options: <span class="macro">vec!</span>[],
<a href=#636 id=636 data-nosnippet>636</a> characteristics: <span class="prelude-val">None</span>,
<a href=#637 id=637 data-nosnippet>637</a> }),
<a href=#638 id=638 data-nosnippet>638</a> }],
<a href=#639 id=639 data-nosnippet>639</a> };
<a href=#640 id=640 data-nosnippet>640</a> <span class="macro">assert!</span>(has_primary_key_option(<span class="kw-2">&amp;</span>column_def));
<a href=#641 id=641 data-nosnippet>641</a> }
<a href=#642 id=642 data-nosnippet>642</a>
<a href=#643 id=643 data-nosnippet>643</a> <span class="attr">#[test]
<a href=#644 id=644 data-nosnippet>644</a> </span><span class="kw">pub fn </span>test_column_to_schema() {
<a href=#645 id=645 data-nosnippet>645</a> <span class="kw">let </span>column_def = Column {
<a href=#646 id=646 data-nosnippet>646</a> column_def: ColumnDef {
<a href=#647 id=647 data-nosnippet>647</a> name: <span class="string">"col"</span>.into(),
<a href=#648 id=648 data-nosnippet>648</a> data_type: SqlDataType::Double(ExactNumberInfo::None),
<a href=#649 id=649 data-nosnippet>649</a> options: <span class="macro">vec!</span>[],
<a href=#650 id=650 data-nosnippet>650</a> },
<a href=#651 id=651 data-nosnippet>651</a> extensions: ColumnExtensions::default(),
<a href=#652 id=652 data-nosnippet>652</a> };
<a href=#653 id=653 data-nosnippet>653</a>
<a href=#654 id=654 data-nosnippet>654</a> <span class="kw">let </span>column_schema = column_to_schema(<span class="kw-2">&amp;</span>column_def, <span class="string">"ts"</span>, <span class="prelude-val">None</span>).unwrap();
<a href=#655 id=655 data-nosnippet>655</a>
<a href=#656 id=656 data-nosnippet>656</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, column_schema.name);
<a href=#657 id=657 data-nosnippet>657</a> <span class="macro">assert_eq!</span>(
<a href=#658 id=658 data-nosnippet>658</a> ConcreteDataType::float64_datatype(),
<a href=#659 id=659 data-nosnippet>659</a> column_schema.data_type
<a href=#660 id=660 data-nosnippet>660</a> );
<a href=#661 id=661 data-nosnippet>661</a> <span class="macro">assert!</span>(column_schema.is_nullable());
<a href=#662 id=662 data-nosnippet>662</a> <span class="macro">assert!</span>(!column_schema.is_time_index());
<a href=#663 id=663 data-nosnippet>663</a>
<a href=#664 id=664 data-nosnippet>664</a> <span class="kw">let </span>column_schema = column_to_schema(<span class="kw-2">&amp;</span>column_def, <span class="string">"col"</span>, <span class="prelude-val">None</span>).unwrap();
<a href=#665 id=665 data-nosnippet>665</a>
<a href=#666 id=666 data-nosnippet>666</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, column_schema.name);
<a href=#667 id=667 data-nosnippet>667</a> <span class="macro">assert_eq!</span>(
<a href=#668 id=668 data-nosnippet>668</a> ConcreteDataType::float64_datatype(),
<a href=#669 id=669 data-nosnippet>669</a> column_schema.data_type
<a href=#670 id=670 data-nosnippet>670</a> );
<a href=#671 id=671 data-nosnippet>671</a> <span class="macro">assert!</span>(!column_schema.is_nullable());
<a href=#672 id=672 data-nosnippet>672</a> <span class="macro">assert!</span>(column_schema.is_time_index());
<a href=#673 id=673 data-nosnippet>673</a>
<a href=#674 id=674 data-nosnippet>674</a> <span class="kw">let </span>column_def = Column {
<a href=#675 id=675 data-nosnippet>675</a> column_def: ColumnDef {
<a href=#676 id=676 data-nosnippet>676</a> name: <span class="string">"col2"</span>.into(),
<a href=#677 id=677 data-nosnippet>677</a> data_type: SqlDataType::String(<span class="prelude-val">None</span>),
<a href=#678 id=678 data-nosnippet>678</a> options: <span class="macro">vec!</span>[
<a href=#679 id=679 data-nosnippet>679</a> ColumnOptionDef {
<a href=#680 id=680 data-nosnippet>680</a> name: <span class="prelude-val">None</span>,
<a href=#681 id=681 data-nosnippet>681</a> option: ColumnOption::NotNull,
<a href=#682 id=682 data-nosnippet>682</a> },
<a href=#683 id=683 data-nosnippet>683</a> ColumnOptionDef {
<a href=#684 id=684 data-nosnippet>684</a> name: <span class="prelude-val">None</span>,
<a href=#685 id=685 data-nosnippet>685</a> option: ColumnOption::Comment(<span class="string">"test comment"</span>.to_string()),
<a href=#686 id=686 data-nosnippet>686</a> },
<a href=#687 id=687 data-nosnippet>687</a> ],
<a href=#688 id=688 data-nosnippet>688</a> },
<a href=#689 id=689 data-nosnippet>689</a> extensions: ColumnExtensions::default(),
<a href=#690 id=690 data-nosnippet>690</a> };
<a href=#691 id=691 data-nosnippet>691</a>
<a href=#692 id=692 data-nosnippet>692</a> <span class="kw">let </span>column_schema = column_to_schema(<span class="kw-2">&amp;</span>column_def, <span class="string">"ts"</span>, <span class="prelude-val">None</span>).unwrap();
<a href=#693 id=693 data-nosnippet>693</a>
<a href=#694 id=694 data-nosnippet>694</a> <span class="macro">assert_eq!</span>(<span class="string">"col2"</span>, column_schema.name);
<a href=#695 id=695 data-nosnippet>695</a> <span class="macro">assert_eq!</span>(ConcreteDataType::string_datatype(), column_schema.data_type);
<a href=#696 id=696 data-nosnippet>696</a> <span class="macro">assert!</span>(!column_schema.is_nullable());
<a href=#697 id=697 data-nosnippet>697</a> <span class="macro">assert!</span>(!column_schema.is_time_index());
<a href=#698 id=698 data-nosnippet>698</a> <span class="macro">assert_eq!</span>(
<a href=#699 id=699 data-nosnippet>699</a> column_schema.metadata().get(COMMENT_KEY),
<a href=#700 id=700 data-nosnippet>700</a> <span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span><span class="string">"test comment"</span>.to_string())
<a href=#701 id=701 data-nosnippet>701</a> );
<a href=#702 id=702 data-nosnippet>702</a> }
<a href=#703 id=703 data-nosnippet>703</a>
<a href=#704 id=704 data-nosnippet>704</a> <span class="attr">#[test]
<a href=#705 id=705 data-nosnippet>705</a> </span><span class="kw">fn </span>test_new_json2_column_uses_v2_layout() -&gt; std::result::Result&lt;(), Box&lt;<span class="kw">dyn </span>std::error::Error&gt;&gt;
<a href=#706 id=706 data-nosnippet>706</a> {
<a href=#707 id=707 data-nosnippet>707</a> <span class="kw">let </span>column = Column {
<a href=#708 id=708 data-nosnippet>708</a> column_def: ColumnDef {
<a href=#709 id=709 data-nosnippet>709</a> name: <span class="string">"data"</span>.into(),
<a href=#710 id=710 data-nosnippet>710</a> data_type: SqlDataType::Custom(
<a href=#711 id=711 data-nosnippet>711</a> sqlparser::ast::ObjectName::from(<span class="macro">vec!</span>[<span class="string">"JSON2"</span>.into()]),
<a href=#712 id=712 data-nosnippet>712</a> <span class="macro">vec!</span>[],
<a href=#713 id=713 data-nosnippet>713</a> ),
<a href=#714 id=714 data-nosnippet>714</a> options: <span class="macro">vec!</span>[],
<a href=#715 id=715 data-nosnippet>715</a> },
<a href=#716 id=716 data-nosnippet>716</a> extensions: ColumnExtensions::default(),
<a href=#717 id=717 data-nosnippet>717</a> };
<a href=#718 id=718 data-nosnippet>718</a>
<a href=#719 id=719 data-nosnippet>719</a> <span class="kw">let </span>schema = column_to_schema(<span class="kw-2">&amp;</span>column, <span class="string">"ts"</span>, <span class="prelude-val">None</span>)<span class="question-mark">?</span>;
<a href=#720 id=720 data-nosnippet>720</a> <span class="kw">let </span>metadata: serde_json::Value =
<a href=#721 id=721 data-nosnippet>721</a> serde_json::from_str(schema.metadata().get(<span class="string">"ARROW:extension:metadata"</span>).unwrap())<span class="question-mark">?</span>;
<a href=#722 id=722 data-nosnippet>722</a> <span class="macro">assert_eq!</span>(<span class="prelude-val">Some</span>(<span class="number">2</span>), metadata[<span class="string">"layout_version"</span>].as_u64());
<a href=#723 id=723 data-nosnippet>723</a> <span class="macro">assert_eq!</span>(
<a href=#724 id=724 data-nosnippet>724</a> <span class="prelude-val">Some</span>(<span class="number">100</span>),
<a href=#725 id=725 data-nosnippet>725</a> metadata[<span class="string">"json_settings"</span>][<span class="string">"max_auto_expanded_paths"</span>].as_u64()
<a href=#726 id=726 data-nosnippet>726</a> );
<a href=#727 id=727 data-nosnippet>727</a>
<a href=#728 id=728 data-nosnippet>728</a> <span class="kw">let </span><span class="kw-2">mut </span>hinted = column;
<a href=#729 id=729 data-nosnippet>729</a> hinted
<a href=#730 id=730 data-nosnippet>730</a> .extensions
<a href=#731 id=731 data-nosnippet>731</a> .set_json_settings(datatypes::json::JsonSettings::try_new(
<a href=#732 id=732 data-nosnippet>732</a> <span class="macro">vec!</span>[datatypes::json::JsonTypeHint {
<a href=#733 id=733 data-nosnippet>733</a> path: <span class="macro">vec!</span>[<span class="string">"kind"</span>.to_string()],
<a href=#734 id=734 data-nosnippet>734</a> data_type: ConcreteDataType::string_datatype(),
<a href=#735 id=735 data-nosnippet>735</a> inverted_index: <span class="bool-val">false</span>,
<a href=#736 id=736 data-nosnippet>736</a> }],
<a href=#737 id=737 data-nosnippet>737</a> <span class="prelude-val">None</span>,
<a href=#738 id=738 data-nosnippet>738</a> )<span class="question-mark">?</span>)<span class="question-mark">?</span>;
<a href=#739 id=739 data-nosnippet>739</a> <span class="kw">let </span>schema = column_to_schema(<span class="kw-2">&amp;</span>hinted, <span class="string">"ts"</span>, <span class="prelude-val">None</span>)<span class="question-mark">?</span>;
<a href=#740 id=740 data-nosnippet>740</a> <span class="kw">let </span>metadata: serde_json::Value =
<a href=#741 id=741 data-nosnippet>741</a> serde_json::from_str(schema.metadata().get(<span class="string">"ARROW:extension:metadata"</span>).unwrap())<span class="question-mark">?</span>;
<a href=#742 id=742 data-nosnippet>742</a> <span class="macro">assert_eq!</span>(
<a href=#743 id=743 data-nosnippet>743</a> <span class="prelude-val">Some</span>(<span class="number">100</span>),
<a href=#744 id=744 data-nosnippet>744</a> metadata[<span class="string">"json_settings"</span>][<span class="string">"max_auto_expanded_paths"</span>].as_u64()
<a href=#745 id=745 data-nosnippet>745</a> );
<a href=#746 id=746 data-nosnippet>746</a> <span class="prelude-val">Ok</span>(())
<a href=#747 id=747 data-nosnippet>747</a> }
<a href=#748 id=748 data-nosnippet>748</a>
<a href=#749 id=749 data-nosnippet>749</a> <span class="attr">#[test]
<a href=#750 id=750 data-nosnippet>750</a> </span><span class="kw">pub fn </span>test_column_to_schema_timestamp_with_timezone() {
<a href=#751 id=751 data-nosnippet>751</a> <span class="kw">let </span>column = Column {
<a href=#752 id=752 data-nosnippet>752</a> column_def: ColumnDef {
<a href=#753 id=753 data-nosnippet>753</a> name: <span class="string">"col"</span>.into(),
<a href=#754 id=754 data-nosnippet>754</a> <span class="comment">// MILLISECOND
<a href=#755 id=755 data-nosnippet>755</a> </span>data_type: SqlDataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">3</span>), TimezoneInfo::None),
<a href=#756 id=756 data-nosnippet>756</a> options: <span class="macro">vec!</span>[ColumnOptionDef {
<a href=#757 id=757 data-nosnippet>757</a> name: <span class="prelude-val">None</span>,
<a href=#758 id=758 data-nosnippet>758</a> option: ColumnOption::Default(Expr::Value(
<a href=#759 id=759 data-nosnippet>759</a> SqlValue::SingleQuotedString(<span class="string">"2024-01-30T00:01:01"</span>.to_string()).into(),
<a href=#760 id=760 data-nosnippet>760</a> )),
<a href=#761 id=761 data-nosnippet>761</a> }],
<a href=#762 id=762 data-nosnippet>762</a> },
<a href=#763 id=763 data-nosnippet>763</a> extensions: ColumnExtensions::default(),
<a href=#764 id=764 data-nosnippet>764</a> };
<a href=#765 id=765 data-nosnippet>765</a>
<a href=#766 id=766 data-nosnippet>766</a> <span class="comment">// with timezone "Asia/Shanghai"
<a href=#767 id=767 data-nosnippet>767</a>
<a href=#768 id=768 data-nosnippet>768</a> </span><span class="kw">let </span>column_schema = column_to_schema(
<a href=#769 id=769 data-nosnippet>769</a> <span class="kw-2">&amp;</span>column,
<a href=#770 id=770 data-nosnippet>770</a> <span class="string">"ts"</span>,
<a href=#771 id=771 data-nosnippet>771</a> <span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>Timezone::from_tz_string(<span class="string">"Asia/Shanghai"</span>).unwrap()),
<a href=#772 id=772 data-nosnippet>772</a> )
<a href=#773 id=773 data-nosnippet>773</a> .unwrap();
<a href=#774 id=774 data-nosnippet>774</a>
<a href=#775 id=775 data-nosnippet>775</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, column_schema.name);
<a href=#776 id=776 data-nosnippet>776</a> <span class="macro">assert_eq!</span>(
<a href=#777 id=777 data-nosnippet>777</a> ConcreteDataType::timestamp_millisecond_datatype(),
<a href=#778 id=778 data-nosnippet>778</a> column_schema.data_type
<a href=#779 id=779 data-nosnippet>779</a> );
<a href=#780 id=780 data-nosnippet>780</a> <span class="macro">assert!</span>(column_schema.is_nullable());
<a href=#781 id=781 data-nosnippet>781</a>
<a href=#782 id=782 data-nosnippet>782</a> <span class="kw">let </span>constraint = column_schema.default_constraint().unwrap();
<a href=#783 id=783 data-nosnippet>783</a> <span class="macro">assert!</span>(
<a href=#784 id=784 data-nosnippet>784</a> <span class="macro">matches!</span>(constraint, ColumnDefaultConstraint::Value(Value::Timestamp(ts))
<a href=#785 id=785 data-nosnippet>785</a> <span class="kw">if </span>ts.to_iso8601_string() == <span class="string">"2024-01-29 16:01:01+0000"</span>)
<a href=#786 id=786 data-nosnippet>786</a> );
<a href=#787 id=787 data-nosnippet>787</a>
<a href=#788 id=788 data-nosnippet>788</a> <span class="comment">// without timezone
<a href=#789 id=789 data-nosnippet>789</a> </span><span class="kw">let </span>column_schema = column_to_schema(<span class="kw-2">&amp;</span>column, <span class="string">"ts"</span>, <span class="prelude-val">None</span>).unwrap();
<a href=#790 id=790 data-nosnippet>790</a>
<a href=#791 id=791 data-nosnippet>791</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, column_schema.name);
<a href=#792 id=792 data-nosnippet>792</a> <span class="macro">assert_eq!</span>(
<a href=#793 id=793 data-nosnippet>793</a> ConcreteDataType::timestamp_millisecond_datatype(),
<a href=#794 id=794 data-nosnippet>794</a> column_schema.data_type
<a href=#795 id=795 data-nosnippet>795</a> );
<a href=#796 id=796 data-nosnippet>796</a> <span class="macro">assert!</span>(column_schema.is_nullable());
<a href=#797 id=797 data-nosnippet>797</a>
<a href=#798 id=798 data-nosnippet>798</a> <span class="kw">let </span>constraint = column_schema.default_constraint().unwrap();
<a href=#799 id=799 data-nosnippet>799</a> <span class="macro">assert!</span>(
<a href=#800 id=800 data-nosnippet>800</a> <span class="macro">matches!</span>(constraint, ColumnDefaultConstraint::Value(Value::Timestamp(ts))
<a href=#801 id=801 data-nosnippet>801</a> <span class="kw">if </span>ts.to_iso8601_string() == <span class="string">"2024-01-30 00:01:01+0000"</span>)
<a href=#802 id=802 data-nosnippet>802</a> );
<a href=#803 id=803 data-nosnippet>803</a> }
<a href=#804 id=804 data-nosnippet>804</a>
<a href=#805 id=805 data-nosnippet>805</a> <span class="attr">#[test]
<a href=#806 id=806 data-nosnippet>806</a> </span><span class="kw">fn </span>test_column_to_schema_with_fulltext() {
<a href=#807 id=807 data-nosnippet>807</a> <span class="kw">let </span>column = Column {
<a href=#808 id=808 data-nosnippet>808</a> column_def: ColumnDef {
<a href=#809 id=809 data-nosnippet>809</a> name: <span class="string">"col"</span>.into(),
<a href=#810 id=810 data-nosnippet>810</a> data_type: SqlDataType::Text,
<a href=#811 id=811 data-nosnippet>811</a> options: <span class="macro">vec!</span>[],
<a href=#812 id=812 data-nosnippet>812</a> },
<a href=#813 id=813 data-nosnippet>813</a> extensions: ColumnExtensions {
<a href=#814 id=814 data-nosnippet>814</a> fulltext_index_options: <span class="prelude-val">Some</span>(OptionMap::from([
<a href=#815 id=815 data-nosnippet>815</a> (
<a href=#816 id=816 data-nosnippet>816</a> COLUMN_FULLTEXT_OPT_KEY_ANALYZER.to_string(),
<a href=#817 id=817 data-nosnippet>817</a> <span class="string">"English"</span>.to_string(),
<a href=#818 id=818 data-nosnippet>818</a> ),
<a href=#819 id=819 data-nosnippet>819</a> (
<a href=#820 id=820 data-nosnippet>820</a> COLUMN_FULLTEXT_OPT_KEY_CASE_SENSITIVE.to_string(),
<a href=#821 id=821 data-nosnippet>821</a> <span class="string">"true"</span>.to_string(),
<a href=#822 id=822 data-nosnippet>822</a> ),
<a href=#823 id=823 data-nosnippet>823</a> ])),
<a href=#824 id=824 data-nosnippet>824</a> ..Default::default()
<a href=#825 id=825 data-nosnippet>825</a> },
<a href=#826 id=826 data-nosnippet>826</a> };
<a href=#827 id=827 data-nosnippet>827</a>
<a href=#828 id=828 data-nosnippet>828</a> <span class="kw">let </span>column_schema = column_to_schema(<span class="kw-2">&amp;</span>column, <span class="string">"ts"</span>, <span class="prelude-val">None</span>).unwrap();
<a href=#829 id=829 data-nosnippet>829</a> <span class="macro">assert_eq!</span>(<span class="string">"col"</span>, column_schema.name);
<a href=#830 id=830 data-nosnippet>830</a> <span class="macro">assert_eq!</span>(ConcreteDataType::string_datatype(), column_schema.data_type);
<a href=#831 id=831 data-nosnippet>831</a> <span class="kw">let </span>fulltext_options = column_schema.fulltext_options().unwrap().unwrap();
<a href=#832 id=832 data-nosnippet>832</a> <span class="macro">assert_eq!</span>(fulltext_options.analyzer, FulltextAnalyzer::English);
<a href=#833 id=833 data-nosnippet>833</a> <span class="macro">assert!</span>(fulltext_options.case_sensitive);
<a href=#834 id=834 data-nosnippet>834</a> }
<a href=#835 id=835 data-nosnippet>835</a>}
</code></pre></div></section></main></body></html>
+36
View File
@@ -0,0 +1,36 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/admin.rs`."><title>admin.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>admin.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::ast::Function;
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="doccomment">/// `ADMIN` statement to execute some administration commands.
<a href=#23 id=23 data-nosnippet>23</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">pub enum </span>Admin {
<a href=#25 id=25 data-nosnippet>25</a> <span class="doccomment">/// Run a admin function.
<a href=#26 id=26 data-nosnippet>26</a> </span>Func(Function),
<a href=#27 id=27 data-nosnippet>27</a>}
<a href=#28 id=28 data-nosnippet>28</a>
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">impl </span>Display <span class="kw">for </span>Admin {
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#32 id=32 data-nosnippet>32</a> Admin::Func(func) =&gt; <span class="macro">write!</span>(f, <span class="string">"ADMIN {func}"</span>),
<a href=#33 id=33 data-nosnippet>33</a> }
<a href=#34 id=34 data-nosnippet>34</a> }
<a href=#35 id=35 data-nosnippet>35</a>}
</code></pre></div></section></main></body></html>
+710
View File
@@ -0,0 +1,710 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/alter.rs`."><title>alter.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>alter.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#16 id=16 data-nosnippet>16</a></span><span class="kw">pub mod </span>trigger;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>std::fmt::{Debug, Display};
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>api::v1;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>common_query::AddColumnLocation;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>datatypes::schema::{FulltextOptions, SkippingIndexOptions};
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>itertools::Itertools;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span>serde::Serialize;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span>sqlparser::ast::{DataType, Expr, Ident, ObjectName, TableConstraint};
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#27 id=27 data-nosnippet>27</a>
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">use </span><span class="kw">crate</span>::statements::OptionMap;
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">use </span><span class="kw">crate</span>::statements::create::{Column, Json2Options, Partitions};
<a href=#30 id=30 data-nosnippet>30</a>
<a href=#31 id=31 data-nosnippet>31</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#32 id=32 data-nosnippet>32</a></span><span class="kw">pub struct </span>AlterTable {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">pub </span>table_name: ObjectName,
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">pub </span>alter_operation: AlterTableOperation,
<a href=#35 id=35 data-nosnippet>35</a> <span class="doccomment">/// Table options in `WITH`. All keys are lowercase.
<a href=#36 id=36 data-nosnippet>36</a> </span><span class="kw">pub </span>options: OptionMap,
<a href=#37 id=37 data-nosnippet>37</a>}
<a href=#38 id=38 data-nosnippet>38</a>
<a href=#39 id=39 data-nosnippet>39</a><span class="kw">impl </span>AlterTable {
<a href=#40 id=40 data-nosnippet>40</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>new(
<a href=#41 id=41 data-nosnippet>41</a> table_name: ObjectName,
<a href=#42 id=42 data-nosnippet>42</a> alter_operation: AlterTableOperation,
<a href=#43 id=43 data-nosnippet>43</a> options: OptionMap,
<a href=#44 id=44 data-nosnippet>44</a> ) -&gt; <span class="self">Self </span>{
<a href=#45 id=45 data-nosnippet>45</a> <span class="self">Self </span>{
<a href=#46 id=46 data-nosnippet>46</a> table_name,
<a href=#47 id=47 data-nosnippet>47</a> alter_operation,
<a href=#48 id=48 data-nosnippet>48</a> options,
<a href=#49 id=49 data-nosnippet>49</a> }
<a href=#50 id=50 data-nosnippet>50</a> }
<a href=#51 id=51 data-nosnippet>51</a>
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">pub fn </span>table_name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw-2">&amp;</span><span class="self">self</span>.table_name
<a href=#54 id=54 data-nosnippet>54</a> }
<a href=#55 id=55 data-nosnippet>55</a>
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">pub fn </span>alter_operation(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>AlterTableOperation {
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw-2">&amp;</span><span class="self">self</span>.alter_operation
<a href=#58 id=58 data-nosnippet>58</a> }
<a href=#59 id=59 data-nosnippet>59</a>
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">pub fn </span>options(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>OptionMap {
<a href=#61 id=61 data-nosnippet>61</a> <span class="kw-2">&amp;</span><span class="self">self</span>.options
<a href=#62 id=62 data-nosnippet>62</a> }
<a href=#63 id=63 data-nosnippet>63</a>
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">pub fn </span>alter_operation_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span>AlterTableOperation {
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw-2">&amp;mut </span><span class="self">self</span>.alter_operation
<a href=#66 id=66 data-nosnippet>66</a> }
<a href=#67 id=67 data-nosnippet>67</a>}
<a href=#68 id=68 data-nosnippet>68</a>
<a href=#69 id=69 data-nosnippet>69</a><span class="kw">impl </span>Display <span class="kw">for </span>AlterTable {
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">let </span>table_name = <span class="self">self</span>.table_name();
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">let </span>alter_operation = <span class="self">self</span>.alter_operation();
<a href=#73 id=73 data-nosnippet>73</a> <span class="macro">write!</span>(f, <span class="string">r#"ALTER TABLE {table_name} {alter_operation}"#</span>)
<a href=#74 id=74 data-nosnippet>74</a> }
<a href=#75 id=75 data-nosnippet>75</a>}
<a href=#76 id=76 data-nosnippet>76</a>
<a href=#77 id=77 data-nosnippet>77</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#78 id=78 data-nosnippet>78</a></span><span class="kw">pub enum </span>AlterTableOperation {
<a href=#79 id=79 data-nosnippet>79</a> <span class="doccomment">/// `ADD &lt;table_constraint&gt;`
<a href=#80 id=80 data-nosnippet>80</a> </span>AddConstraint(TableConstraint),
<a href=#81 id=81 data-nosnippet>81</a> <span class="doccomment">/// `ADD [ COLUMN ] &lt;column_def&gt; [location]`
<a href=#82 id=82 data-nosnippet>82</a> </span>AddColumns {
<a href=#83 id=83 data-nosnippet>83</a> add_columns: Vec&lt;AddColumn&gt;,
<a href=#84 id=84 data-nosnippet>84</a> },
<a href=#85 id=85 data-nosnippet>85</a> <span class="doccomment">/// `MODIFY &lt;column_name&gt; [target_type]`
<a href=#86 id=86 data-nosnippet>86</a> </span>ModifyColumnType {
<a href=#87 id=87 data-nosnippet>87</a> column_name: Ident,
<a href=#88 id=88 data-nosnippet>88</a> target_type: DataType,
<a href=#89 id=89 data-nosnippet>89</a> json2_options: <span class="prelude-ty">Option</span>&lt;Json2Options&gt;,
<a href=#90 id=90 data-nosnippet>90</a> },
<a href=#91 id=91 data-nosnippet>91</a> <span class="doccomment">/// `MODIFY &lt;column_name&gt; JSON2 [json2_options]`
<a href=#92 id=92 data-nosnippet>92</a> </span>SetJsonSettings {
<a href=#93 id=93 data-nosnippet>93</a> column_name: Ident,
<a href=#94 id=94 data-nosnippet>94</a> json2_options: <span class="prelude-ty">Option</span>&lt;Json2Options&gt;,
<a href=#95 id=95 data-nosnippet>95</a> },
<a href=#96 id=96 data-nosnippet>96</a> <span class="doccomment">/// `SET &lt;table attrs key&gt; = &lt;table attr value&gt;`
<a href=#97 id=97 data-nosnippet>97</a> </span>SetTableOptions {
<a href=#98 id=98 data-nosnippet>98</a> options: Vec&lt;KeyValueOption&gt;,
<a href=#99 id=99 data-nosnippet>99</a> },
<a href=#100 id=100 data-nosnippet>100</a> <span class="doccomment">/// `UNSET &lt;table attrs key&gt;`
<a href=#101 id=101 data-nosnippet>101</a> </span>UnsetTableOptions {
<a href=#102 id=102 data-nosnippet>102</a> keys: Vec&lt;String&gt;,
<a href=#103 id=103 data-nosnippet>103</a> },
<a href=#104 id=104 data-nosnippet>104</a> <span class="doccomment">/// `DROP COLUMN &lt;name&gt;`
<a href=#105 id=105 data-nosnippet>105</a> </span>DropColumn {
<a href=#106 id=106 data-nosnippet>106</a> name: Ident,
<a href=#107 id=107 data-nosnippet>107</a> },
<a href=#108 id=108 data-nosnippet>108</a> <span class="doccomment">/// `RENAME &lt;new_table_name&gt;`
<a href=#109 id=109 data-nosnippet>109</a> </span>RenameTable {
<a href=#110 id=110 data-nosnippet>110</a> new_table_name: String,
<a href=#111 id=111 data-nosnippet>111</a> },
<a href=#112 id=112 data-nosnippet>112</a> SetIndex {
<a href=#113 id=113 data-nosnippet>113</a> options: SetIndexOperation,
<a href=#114 id=114 data-nosnippet>114</a> },
<a href=#115 id=115 data-nosnippet>115</a> UnsetIndex {
<a href=#116 id=116 data-nosnippet>116</a> options: UnsetIndexOperation,
<a href=#117 id=117 data-nosnippet>117</a> },
<a href=#118 id=118 data-nosnippet>118</a> DropDefaults {
<a href=#119 id=119 data-nosnippet>119</a> columns: Vec&lt;DropDefaultsOperation&gt;,
<a href=#120 id=120 data-nosnippet>120</a> },
<a href=#121 id=121 data-nosnippet>121</a> <span class="doccomment">/// `ALTER &lt;column_name&gt; SET DEFAULT &lt;default_value&gt;`
<a href=#122 id=122 data-nosnippet>122</a> </span>SetDefaults {
<a href=#123 id=123 data-nosnippet>123</a> defaults: Vec&lt;SetDefaultsOperation&gt;,
<a href=#124 id=124 data-nosnippet>124</a> },
<a href=#125 id=125 data-nosnippet>125</a> <span class="doccomment">/// `REPARTITION (...) INTO (...)`
<a href=#126 id=126 data-nosnippet>126</a> </span>Repartition {
<a href=#127 id=127 data-nosnippet>127</a> operation: RepartitionOperation,
<a href=#128 id=128 data-nosnippet>128</a> },
<a href=#129 id=129 data-nosnippet>129</a> <span class="doccomment">/// `PARTITION ON COLUMNS (...) (...)`
<a href=#130 id=130 data-nosnippet>130</a> </span>Partition {
<a href=#131 id=131 data-nosnippet>131</a> partitions: Partitions,
<a href=#132 id=132 data-nosnippet>132</a> },
<a href=#133 id=133 data-nosnippet>133</a>}
<a href=#134 id=134 data-nosnippet>134</a>
<a href=#135 id=135 data-nosnippet>135</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#136 id=136 data-nosnippet>136</a></span><span class="doccomment">/// `ALTER &lt;column_name&gt; DROP DEFAULT`
<a href=#137 id=137 data-nosnippet>137</a></span><span class="kw">pub struct </span>DropDefaultsOperation(<span class="kw">pub </span>Ident);
<a href=#138 id=138 data-nosnippet>138</a>
<a href=#139 id=139 data-nosnippet>139</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#140 id=140 data-nosnippet>140</a></span><span class="kw">pub struct </span>SetDefaultsOperation {
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">pub </span>column_name: Ident,
<a href=#142 id=142 data-nosnippet>142</a> <span class="kw">pub </span>default_constraint: Expr,
<a href=#143 id=143 data-nosnippet>143</a>}
<a href=#144 id=144 data-nosnippet>144</a>
<a href=#145 id=145 data-nosnippet>145</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#146 id=146 data-nosnippet>146</a></span><span class="kw">pub struct </span>RepartitionOperation {
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw">pub </span>from_exprs: Vec&lt;Expr&gt;,
<a href=#148 id=148 data-nosnippet>148</a> <span class="kw">pub </span>into_exprs: Vec&lt;Expr&gt;,
<a href=#149 id=149 data-nosnippet>149</a> <span class="doccomment">/// Optional new partition columns for `REPARTITION ... ON COLUMNS (...) INTO (...)` and
<a href=#150 id=150 data-nosnippet>150</a> /// `SPLIT PARTITION ... ON COLUMNS (...) INTO (...)`.
<a href=#151 id=151 data-nosnippet>151</a> ///
<a href=#152 id=152 data-nosnippet>152</a> /// This is `Some` only when the statement explicitly carries `ON COLUMNS`.
<a href=#153 id=153 data-nosnippet>153</a> /// Legacy `REPARTITION`, `SPLIT PARTITION`, and `MERGE PARTITION` keep this as `None`.
<a href=#154 id=154 data-nosnippet>154</a> </span><span class="kw">pub </span>partition_columns: <span class="prelude-ty">Option</span>&lt;Vec&lt;Ident&gt;&gt;,
<a href=#155 id=155 data-nosnippet>155</a>}
<a href=#156 id=156 data-nosnippet>156</a>
<a href=#157 id=157 data-nosnippet>157</a><span class="kw">impl </span>RepartitionOperation {
<a href=#158 id=158 data-nosnippet>158</a> <span class="kw">pub fn </span>new(from_exprs: Vec&lt;Expr&gt;, into_exprs: Vec&lt;Expr&gt;) -&gt; <span class="self">Self </span>{
<a href=#159 id=159 data-nosnippet>159</a> <span class="self">Self </span>{
<a href=#160 id=160 data-nosnippet>160</a> from_exprs,
<a href=#161 id=161 data-nosnippet>161</a> into_exprs,
<a href=#162 id=162 data-nosnippet>162</a> partition_columns: <span class="prelude-val">None</span>,
<a href=#163 id=163 data-nosnippet>163</a> }
<a href=#164 id=164 data-nosnippet>164</a> }
<a href=#165 id=165 data-nosnippet>165</a>
<a href=#166 id=166 data-nosnippet>166</a> <span class="kw">pub fn </span>with_partition_columns(
<a href=#167 id=167 data-nosnippet>167</a> from_exprs: Vec&lt;Expr&gt;,
<a href=#168 id=168 data-nosnippet>168</a> into_exprs: Vec&lt;Expr&gt;,
<a href=#169 id=169 data-nosnippet>169</a> partition_columns: Vec&lt;Ident&gt;,
<a href=#170 id=170 data-nosnippet>170</a> ) -&gt; <span class="self">Self </span>{
<a href=#171 id=171 data-nosnippet>171</a> <span class="self">Self </span>{
<a href=#172 id=172 data-nosnippet>172</a> from_exprs,
<a href=#173 id=173 data-nosnippet>173</a> into_exprs,
<a href=#174 id=174 data-nosnippet>174</a> partition_columns: <span class="prelude-val">Some</span>(partition_columns),
<a href=#175 id=175 data-nosnippet>175</a> }
<a href=#176 id=176 data-nosnippet>176</a> }
<a href=#177 id=177 data-nosnippet>177</a>}
<a href=#178 id=178 data-nosnippet>178</a>
<a href=#179 id=179 data-nosnippet>179</a><span class="kw">impl </span>Display <span class="kw">for </span>RepartitionOperation {
<a href=#180 id=180 data-nosnippet>180</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#181 id=181 data-nosnippet>181</a> <span class="kw">let </span>from = <span class="self">self
<a href=#182 id=182 data-nosnippet>182</a> </span>.from_exprs
<a href=#183 id=183 data-nosnippet>183</a> .iter()
<a href=#184 id=184 data-nosnippet>184</a> .map(|expr| expr.to_string())
<a href=#185 id=185 data-nosnippet>185</a> .join(<span class="string">", "</span>);
<a href=#186 id=186 data-nosnippet>186</a> <span class="kw">let </span>into = <span class="self">self
<a href=#187 id=187 data-nosnippet>187</a> </span>.into_exprs
<a href=#188 id=188 data-nosnippet>188</a> .iter()
<a href=#189 id=189 data-nosnippet>189</a> .map(|expr| expr.to_string())
<a href=#190 id=190 data-nosnippet>190</a> .join(<span class="string">", "</span>);
<a href=#191 id=191 data-nosnippet>191</a>
<a href=#192 id=192 data-nosnippet>192</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(partition_columns) = <span class="kw-2">&amp;</span><span class="self">self</span>.partition_columns {
<a href=#193 id=193 data-nosnippet>193</a> <span class="kw">let </span>partition_columns = partition_columns
<a href=#194 id=194 data-nosnippet>194</a> .iter()
<a href=#195 id=195 data-nosnippet>195</a> .map(|ident| ident.to_string())
<a href=#196 id=196 data-nosnippet>196</a> .join(<span class="string">", "</span>);
<a href=#197 id=197 data-nosnippet>197</a> <span class="macro">write!</span>(f, <span class="string">"({from}) ON COLUMNS ({partition_columns}) INTO ({into})"</span>)
<a href=#198 id=198 data-nosnippet>198</a> } <span class="kw">else </span>{
<a href=#199 id=199 data-nosnippet>199</a> <span class="macro">write!</span>(f, <span class="string">"({from}) INTO ({into})"</span>)
<a href=#200 id=200 data-nosnippet>200</a> }
<a href=#201 id=201 data-nosnippet>201</a> }
<a href=#202 id=202 data-nosnippet>202</a>}
<a href=#203 id=203 data-nosnippet>203</a>
<a href=#204 id=204 data-nosnippet>204</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#205 id=205 data-nosnippet>205</a></span><span class="kw">pub enum </span>SetIndexOperation {
<a href=#206 id=206 data-nosnippet>206</a> <span class="doccomment">/// `MODIFY COLUMN &lt;column_name&gt; SET FULLTEXT INDEX [WITH &lt;options&gt;]`
<a href=#207 id=207 data-nosnippet>207</a> </span>Fulltext {
<a href=#208 id=208 data-nosnippet>208</a> column_name: Ident,
<a href=#209 id=209 data-nosnippet>209</a> options: FulltextOptions,
<a href=#210 id=210 data-nosnippet>210</a> },
<a href=#211 id=211 data-nosnippet>211</a> <span class="doccomment">/// `MODIFY COLUMN &lt;column_name&gt; SET INVERTED INDEX`
<a href=#212 id=212 data-nosnippet>212</a> </span>Inverted { column_name: Ident },
<a href=#213 id=213 data-nosnippet>213</a> <span class="doccomment">/// `MODIFY COLUMN &lt;column_name&gt; SET SKIPPING INDEX`
<a href=#214 id=214 data-nosnippet>214</a> </span>Skipping {
<a href=#215 id=215 data-nosnippet>215</a> column_name: Ident,
<a href=#216 id=216 data-nosnippet>216</a> options: SkippingIndexOptions,
<a href=#217 id=217 data-nosnippet>217</a> },
<a href=#218 id=218 data-nosnippet>218</a>}
<a href=#219 id=219 data-nosnippet>219</a>
<a href=#220 id=220 data-nosnippet>220</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#221 id=221 data-nosnippet>221</a></span><span class="kw">pub enum </span>UnsetIndexOperation {
<a href=#222 id=222 data-nosnippet>222</a> <span class="doccomment">/// `MODIFY COLUMN &lt;column_name&gt; UNSET FULLTEXT INDEX`
<a href=#223 id=223 data-nosnippet>223</a> </span>Fulltext { column_name: Ident },
<a href=#224 id=224 data-nosnippet>224</a> <span class="doccomment">/// `MODIFY COLUMN &lt;column_name&gt; UNSET INVERTED INDEX`
<a href=#225 id=225 data-nosnippet>225</a> </span>Inverted { column_name: Ident },
<a href=#226 id=226 data-nosnippet>226</a> <span class="doccomment">/// `MODIFY COLUMN &lt;column_name&gt; UNSET SKIPPING INDEX`
<a href=#227 id=227 data-nosnippet>227</a> </span>Skipping { column_name: Ident },
<a href=#228 id=228 data-nosnippet>228</a>}
<a href=#229 id=229 data-nosnippet>229</a>
<a href=#230 id=230 data-nosnippet>230</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#231 id=231 data-nosnippet>231</a></span><span class="kw">pub struct </span>AddColumn {
<a href=#232 id=232 data-nosnippet>232</a> <span class="kw">pub </span>column: Column,
<a href=#233 id=233 data-nosnippet>233</a> <span class="kw">pub </span>location: <span class="prelude-ty">Option</span>&lt;AddColumnLocation&gt;,
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">pub </span>add_if_not_exists: bool,
<a href=#235 id=235 data-nosnippet>235</a>}
<a href=#236 id=236 data-nosnippet>236</a>
<a href=#237 id=237 data-nosnippet>237</a><span class="kw">impl </span>Display <span class="kw">for </span>AddColumn {
<a href=#238 id=238 data-nosnippet>238</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#239 id=239 data-nosnippet>239</a> <span class="macro">write!</span>(f, <span class="string">"{}"</span>, <span class="self">self</span>.column)<span class="question-mark">?</span>;
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(location) = <span class="kw-2">&amp;</span><span class="self">self</span>.location {
<a href=#241 id=241 data-nosnippet>241</a> <span class="macro">write!</span>(f, <span class="string">" {location}"</span>)<span class="question-mark">?</span>;
<a href=#242 id=242 data-nosnippet>242</a> }
<a href=#243 id=243 data-nosnippet>243</a> <span class="prelude-val">Ok</span>(())
<a href=#244 id=244 data-nosnippet>244</a> }
<a href=#245 id=245 data-nosnippet>245</a>}
<a href=#246 id=246 data-nosnippet>246</a>
<a href=#247 id=247 data-nosnippet>247</a><span class="kw">impl </span>Display <span class="kw">for </span>AlterTableOperation {
<a href=#248 id=248 data-nosnippet>248</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#249 id=249 data-nosnippet>249</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#250 id=250 data-nosnippet>250</a> AlterTableOperation::AddConstraint(constraint) =&gt; <span class="macro">write!</span>(f, <span class="string">r#"ADD {constraint}"#</span>),
<a href=#251 id=251 data-nosnippet>251</a> AlterTableOperation::AddColumns { add_columns } =&gt; {
<a href=#252 id=252 data-nosnippet>252</a> <span class="kw">let </span>columns = add_columns
<a href=#253 id=253 data-nosnippet>253</a> .iter()
<a href=#254 id=254 data-nosnippet>254</a> .map(|add_column| <span class="macro">format!</span>(<span class="string">"ADD COLUMN {add_column}"</span>))
<a href=#255 id=255 data-nosnippet>255</a> .join(<span class="string">", "</span>);
<a href=#256 id=256 data-nosnippet>256</a> <span class="macro">write!</span>(f, <span class="string">"{columns}"</span>)
<a href=#257 id=257 data-nosnippet>257</a> }
<a href=#258 id=258 data-nosnippet>258</a> AlterTableOperation::DropColumn { name } =&gt; <span class="macro">write!</span>(f, <span class="string">r#"DROP COLUMN {name}"#</span>),
<a href=#259 id=259 data-nosnippet>259</a> AlterTableOperation::RenameTable { new_table_name } =&gt; {
<a href=#260 id=260 data-nosnippet>260</a> <span class="macro">write!</span>(f, <span class="string">r#"RENAME {new_table_name}"#</span>)
<a href=#261 id=261 data-nosnippet>261</a> }
<a href=#262 id=262 data-nosnippet>262</a> AlterTableOperation::ModifyColumnType {
<a href=#263 id=263 data-nosnippet>263</a> column_name,
<a href=#264 id=264 data-nosnippet>264</a> target_type,
<a href=#265 id=265 data-nosnippet>265</a> json2_options,
<a href=#266 id=266 data-nosnippet>266</a> } =&gt; {
<a href=#267 id=267 data-nosnippet>267</a> <span class="macro">write!</span>(f, <span class="string">r#"MODIFY COLUMN {column_name} {target_type}"#</span>)<span class="question-mark">?</span>;
<a href=#268 id=268 data-nosnippet>268</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(options) = json2_options {
<a href=#269 id=269 data-nosnippet>269</a> <span class="macro">write!</span>(f, <span class="string">"{options}"</span>)<span class="question-mark">?</span>;
<a href=#270 id=270 data-nosnippet>270</a> }
<a href=#271 id=271 data-nosnippet>271</a> <span class="prelude-val">Ok</span>(())
<a href=#272 id=272 data-nosnippet>272</a> }
<a href=#273 id=273 data-nosnippet>273</a> AlterTableOperation::SetJsonSettings {
<a href=#274 id=274 data-nosnippet>274</a> column_name,
<a href=#275 id=275 data-nosnippet>275</a> json2_options,
<a href=#276 id=276 data-nosnippet>276</a> } =&gt; {
<a href=#277 id=277 data-nosnippet>277</a> <span class="macro">write!</span>(f, <span class="string">r#"MODIFY COLUMN {column_name} JSON2"#</span>)<span class="question-mark">?</span>;
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(options) = json2_options {
<a href=#279 id=279 data-nosnippet>279</a> <span class="macro">write!</span>(f, <span class="string">"{options}"</span>)<span class="question-mark">?</span>;
<a href=#280 id=280 data-nosnippet>280</a> }
<a href=#281 id=281 data-nosnippet>281</a> <span class="prelude-val">Ok</span>(())
<a href=#282 id=282 data-nosnippet>282</a> }
<a href=#283 id=283 data-nosnippet>283</a> AlterTableOperation::SetTableOptions { options } =&gt; {
<a href=#284 id=284 data-nosnippet>284</a> <span class="kw">let </span>kvs = options
<a href=#285 id=285 data-nosnippet>285</a> .iter()
<a href=#286 id=286 data-nosnippet>286</a> .map(|KeyValueOption { key, value }| {
<a href=#287 id=287 data-nosnippet>287</a> <span class="kw">if </span>!value.is_empty() {
<a href=#288 id=288 data-nosnippet>288</a> <span class="macro">format!</span>(<span class="string">"'{key}'='{value}'"</span>)
<a href=#289 id=289 data-nosnippet>289</a> } <span class="kw">else </span>{
<a href=#290 id=290 data-nosnippet>290</a> <span class="macro">format!</span>(<span class="string">"'{key}'=NULL"</span>)
<a href=#291 id=291 data-nosnippet>291</a> }
<a href=#292 id=292 data-nosnippet>292</a> })
<a href=#293 id=293 data-nosnippet>293</a> .join(<span class="string">","</span>);
<a href=#294 id=294 data-nosnippet>294</a>
<a href=#295 id=295 data-nosnippet>295</a> <span class="macro">write!</span>(f, <span class="string">"SET {kvs}"</span>)
<a href=#296 id=296 data-nosnippet>296</a> }
<a href=#297 id=297 data-nosnippet>297</a> AlterTableOperation::UnsetTableOptions { keys } =&gt; {
<a href=#298 id=298 data-nosnippet>298</a> <span class="kw">let </span>keys = keys.iter().map(|k| <span class="macro">format!</span>(<span class="string">"'{k}'"</span>)).join(<span class="string">","</span>);
<a href=#299 id=299 data-nosnippet>299</a> <span class="macro">write!</span>(f, <span class="string">"UNSET {keys}"</span>)
<a href=#300 id=300 data-nosnippet>300</a> }
<a href=#301 id=301 data-nosnippet>301</a> AlterTableOperation::Repartition { operation } =&gt; {
<a href=#302 id=302 data-nosnippet>302</a> <span class="macro">write!</span>(f, <span class="string">"REPARTITION {operation}"</span>)
<a href=#303 id=303 data-nosnippet>303</a> }
<a href=#304 id=304 data-nosnippet>304</a> AlterTableOperation::Partition { partitions } =&gt; {
<a href=#305 id=305 data-nosnippet>305</a> <span class="macro">write!</span>(f, <span class="string">"{partitions}"</span>)
<a href=#306 id=306 data-nosnippet>306</a> }
<a href=#307 id=307 data-nosnippet>307</a> AlterTableOperation::SetIndex { options } =&gt; <span class="kw">match </span>options {
<a href=#308 id=308 data-nosnippet>308</a> SetIndexOperation::Fulltext {
<a href=#309 id=309 data-nosnippet>309</a> column_name,
<a href=#310 id=310 data-nosnippet>310</a> options,
<a href=#311 id=311 data-nosnippet>311</a> } =&gt; {
<a href=#312 id=312 data-nosnippet>312</a> <span class="macro">write!</span>(
<a href=#313 id=313 data-nosnippet>313</a> f,
<a href=#314 id=314 data-nosnippet>314</a> <span class="string">"MODIFY COLUMN {column_name} SET FULLTEXT INDEX WITH(analyzer={0}, case_sensitive={1}, backend={2})"</span>,
<a href=#315 id=315 data-nosnippet>315</a> options.analyzer, options.case_sensitive, options.backend
<a href=#316 id=316 data-nosnippet>316</a> )
<a href=#317 id=317 data-nosnippet>317</a> }
<a href=#318 id=318 data-nosnippet>318</a> SetIndexOperation::Inverted { column_name } =&gt; {
<a href=#319 id=319 data-nosnippet>319</a> <span class="macro">write!</span>(f, <span class="string">"MODIFY COLUMN {column_name} SET INVERTED INDEX"</span>)
<a href=#320 id=320 data-nosnippet>320</a> }
<a href=#321 id=321 data-nosnippet>321</a> SetIndexOperation::Skipping {
<a href=#322 id=322 data-nosnippet>322</a> column_name,
<a href=#323 id=323 data-nosnippet>323</a> options,
<a href=#324 id=324 data-nosnippet>324</a> } =&gt; {
<a href=#325 id=325 data-nosnippet>325</a> <span class="macro">write!</span>(
<a href=#326 id=326 data-nosnippet>326</a> f,
<a href=#327 id=327 data-nosnippet>327</a> <span class="string">"MODIFY COLUMN {column_name} SET SKIPPING INDEX WITH(granularity={0}, index_type={1})"</span>,
<a href=#328 id=328 data-nosnippet>328</a> options.granularity, options.index_type
<a href=#329 id=329 data-nosnippet>329</a> )
<a href=#330 id=330 data-nosnippet>330</a> }
<a href=#331 id=331 data-nosnippet>331</a> },
<a href=#332 id=332 data-nosnippet>332</a> AlterTableOperation::UnsetIndex { options } =&gt; <span class="kw">match </span>options {
<a href=#333 id=333 data-nosnippet>333</a> UnsetIndexOperation::Fulltext { column_name } =&gt; {
<a href=#334 id=334 data-nosnippet>334</a> <span class="macro">write!</span>(f, <span class="string">"MODIFY COLUMN {column_name} UNSET FULLTEXT INDEX"</span>)
<a href=#335 id=335 data-nosnippet>335</a> }
<a href=#336 id=336 data-nosnippet>336</a> UnsetIndexOperation::Inverted { column_name } =&gt; {
<a href=#337 id=337 data-nosnippet>337</a> <span class="macro">write!</span>(f, <span class="string">"MODIFY COLUMN {column_name} UNSET INVERTED INDEX"</span>)
<a href=#338 id=338 data-nosnippet>338</a> }
<a href=#339 id=339 data-nosnippet>339</a> UnsetIndexOperation::Skipping { column_name } =&gt; {
<a href=#340 id=340 data-nosnippet>340</a> <span class="macro">write!</span>(f, <span class="string">"MODIFY COLUMN {column_name} UNSET SKIPPING INDEX"</span>)
<a href=#341 id=341 data-nosnippet>341</a> }
<a href=#342 id=342 data-nosnippet>342</a> },
<a href=#343 id=343 data-nosnippet>343</a> AlterTableOperation::DropDefaults { columns } =&gt; {
<a href=#344 id=344 data-nosnippet>344</a> <span class="kw">let </span>columns = columns
<a href=#345 id=345 data-nosnippet>345</a> .iter()
<a href=#346 id=346 data-nosnippet>346</a> .map(|column| <span class="macro">format!</span>(<span class="string">"MODIFY COLUMN {} DROP DEFAULT"</span>, column.<span class="number">0</span>))
<a href=#347 id=347 data-nosnippet>347</a> .join(<span class="string">", "</span>);
<a href=#348 id=348 data-nosnippet>348</a> <span class="macro">write!</span>(f, <span class="string">"{columns}"</span>)
<a href=#349 id=349 data-nosnippet>349</a> }
<a href=#350 id=350 data-nosnippet>350</a> AlterTableOperation::SetDefaults { defaults } =&gt; {
<a href=#351 id=351 data-nosnippet>351</a> <span class="kw">let </span>defaults = defaults
<a href=#352 id=352 data-nosnippet>352</a> .iter()
<a href=#353 id=353 data-nosnippet>353</a> .map(|column| {
<a href=#354 id=354 data-nosnippet>354</a> <span class="macro">format!</span>(
<a href=#355 id=355 data-nosnippet>355</a> <span class="string">"MODIFY COLUMN {} SET DEFAULT {}"</span>,
<a href=#356 id=356 data-nosnippet>356</a> column.column_name, column.default_constraint
<a href=#357 id=357 data-nosnippet>357</a> )
<a href=#358 id=358 data-nosnippet>358</a> })
<a href=#359 id=359 data-nosnippet>359</a> .join(<span class="string">", "</span>);
<a href=#360 id=360 data-nosnippet>360</a> <span class="macro">write!</span>(f, <span class="string">"{defaults}"</span>)
<a href=#361 id=361 data-nosnippet>361</a> }
<a href=#362 id=362 data-nosnippet>362</a> }
<a href=#363 id=363 data-nosnippet>363</a> }
<a href=#364 id=364 data-nosnippet>364</a>}
<a href=#365 id=365 data-nosnippet>365</a>
<a href=#366 id=366 data-nosnippet>366</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#367 id=367 data-nosnippet>367</a></span><span class="kw">pub struct </span>KeyValueOption {
<a href=#368 id=368 data-nosnippet>368</a> <span class="kw">pub </span>key: String,
<a href=#369 id=369 data-nosnippet>369</a> <span class="kw">pub </span>value: String,
<a href=#370 id=370 data-nosnippet>370</a>}
<a href=#371 id=371 data-nosnippet>371</a>
<a href=#372 id=372 data-nosnippet>372</a><span class="kw">impl </span>From&lt;KeyValueOption&gt; <span class="kw">for </span>v1::Option {
<a href=#373 id=373 data-nosnippet>373</a> <span class="kw">fn </span>from(c: KeyValueOption) -&gt; <span class="self">Self </span>{
<a href=#374 id=374 data-nosnippet>374</a> v1::Option {
<a href=#375 id=375 data-nosnippet>375</a> key: c.key,
<a href=#376 id=376 data-nosnippet>376</a> value: c.value,
<a href=#377 id=377 data-nosnippet>377</a> }
<a href=#378 id=378 data-nosnippet>378</a> }
<a href=#379 id=379 data-nosnippet>379</a>}
<a href=#380 id=380 data-nosnippet>380</a>
<a href=#381 id=381 data-nosnippet>381</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#382 id=382 data-nosnippet>382</a></span><span class="kw">pub struct </span>AlterDatabase {
<a href=#383 id=383 data-nosnippet>383</a> <span class="kw">pub </span>database_name: ObjectName,
<a href=#384 id=384 data-nosnippet>384</a> <span class="kw">pub </span>alter_operation: AlterDatabaseOperation,
<a href=#385 id=385 data-nosnippet>385</a>}
<a href=#386 id=386 data-nosnippet>386</a>
<a href=#387 id=387 data-nosnippet>387</a><span class="kw">impl </span>AlterDatabase {
<a href=#388 id=388 data-nosnippet>388</a> <span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>new(database_name: ObjectName, alter_operation: AlterDatabaseOperation) -&gt; <span class="self">Self </span>{
<a href=#389 id=389 data-nosnippet>389</a> <span class="self">Self </span>{
<a href=#390 id=390 data-nosnippet>390</a> database_name,
<a href=#391 id=391 data-nosnippet>391</a> alter_operation,
<a href=#392 id=392 data-nosnippet>392</a> }
<a href=#393 id=393 data-nosnippet>393</a> }
<a href=#394 id=394 data-nosnippet>394</a>
<a href=#395 id=395 data-nosnippet>395</a> <span class="kw">pub fn </span>database_name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#396 id=396 data-nosnippet>396</a> <span class="kw-2">&amp;</span><span class="self">self</span>.database_name
<a href=#397 id=397 data-nosnippet>397</a> }
<a href=#398 id=398 data-nosnippet>398</a>
<a href=#399 id=399 data-nosnippet>399</a> <span class="kw">pub fn </span>alter_operation(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>AlterDatabaseOperation {
<a href=#400 id=400 data-nosnippet>400</a> <span class="kw-2">&amp;</span><span class="self">self</span>.alter_operation
<a href=#401 id=401 data-nosnippet>401</a> }
<a href=#402 id=402 data-nosnippet>402</a>}
<a href=#403 id=403 data-nosnippet>403</a>
<a href=#404 id=404 data-nosnippet>404</a><span class="kw">impl </span>Display <span class="kw">for </span>AlterDatabase {
<a href=#405 id=405 data-nosnippet>405</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#406 id=406 data-nosnippet>406</a> <span class="kw">let </span>database_name = <span class="self">self</span>.database_name();
<a href=#407 id=407 data-nosnippet>407</a> <span class="kw">let </span>alter_operation = <span class="self">self</span>.alter_operation();
<a href=#408 id=408 data-nosnippet>408</a> <span class="macro">write!</span>(f, <span class="string">r#"ALTER DATABASE {database_name} {alter_operation}"#</span>)
<a href=#409 id=409 data-nosnippet>409</a> }
<a href=#410 id=410 data-nosnippet>410</a>}
<a href=#411 id=411 data-nosnippet>411</a>
<a href=#412 id=412 data-nosnippet>412</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#413 id=413 data-nosnippet>413</a></span><span class="kw">pub enum </span>AlterDatabaseOperation {
<a href=#414 id=414 data-nosnippet>414</a> SetDatabaseOption { options: Vec&lt;KeyValueOption&gt; },
<a href=#415 id=415 data-nosnippet>415</a> UnsetDatabaseOption { keys: Vec&lt;String&gt; },
<a href=#416 id=416 data-nosnippet>416</a>}
<a href=#417 id=417 data-nosnippet>417</a>
<a href=#418 id=418 data-nosnippet>418</a><span class="kw">impl </span>Display <span class="kw">for </span>AlterDatabaseOperation {
<a href=#419 id=419 data-nosnippet>419</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#420 id=420 data-nosnippet>420</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#421 id=421 data-nosnippet>421</a> AlterDatabaseOperation::SetDatabaseOption { options } =&gt; {
<a href=#422 id=422 data-nosnippet>422</a> <span class="kw">let </span>kvs = options
<a href=#423 id=423 data-nosnippet>423</a> .iter()
<a href=#424 id=424 data-nosnippet>424</a> .map(|KeyValueOption { key, value }| {
<a href=#425 id=425 data-nosnippet>425</a> <span class="kw">if </span>!value.is_empty() {
<a href=#426 id=426 data-nosnippet>426</a> <span class="macro">format!</span>(<span class="string">"'{key}'='{value}'"</span>)
<a href=#427 id=427 data-nosnippet>427</a> } <span class="kw">else </span>{
<a href=#428 id=428 data-nosnippet>428</a> <span class="macro">format!</span>(<span class="string">"'{key}'=NULL"</span>)
<a href=#429 id=429 data-nosnippet>429</a> }
<a href=#430 id=430 data-nosnippet>430</a> })
<a href=#431 id=431 data-nosnippet>431</a> .join(<span class="string">","</span>);
<a href=#432 id=432 data-nosnippet>432</a>
<a href=#433 id=433 data-nosnippet>433</a> <span class="macro">write!</span>(f, <span class="string">"SET {kvs}"</span>)<span class="question-mark">?</span>;
<a href=#434 id=434 data-nosnippet>434</a>
<a href=#435 id=435 data-nosnippet>435</a> <span class="prelude-val">Ok</span>(())
<a href=#436 id=436 data-nosnippet>436</a> }
<a href=#437 id=437 data-nosnippet>437</a> AlterDatabaseOperation::UnsetDatabaseOption { keys } =&gt; {
<a href=#438 id=438 data-nosnippet>438</a> <span class="kw">let </span>keys = keys.iter().map(|key| <span class="macro">format!</span>(<span class="string">"'{key}'"</span>)).join(<span class="string">","</span>);
<a href=#439 id=439 data-nosnippet>439</a> <span class="macro">write!</span>(f, <span class="string">"UNSET {keys}"</span>)<span class="question-mark">?</span>;
<a href=#440 id=440 data-nosnippet>440</a>
<a href=#441 id=441 data-nosnippet>441</a> <span class="prelude-val">Ok</span>(())
<a href=#442 id=442 data-nosnippet>442</a> }
<a href=#443 id=443 data-nosnippet>443</a> }
<a href=#444 id=444 data-nosnippet>444</a> }
<a href=#445 id=445 data-nosnippet>445</a>}
<a href=#446 id=446 data-nosnippet>446</a>
<a href=#447 id=447 data-nosnippet>447</a><span class="attr">#[cfg(test)]
<a href=#448 id=448 data-nosnippet>448</a></span><span class="kw">mod </span>tests {
<a href=#449 id=449 data-nosnippet>449</a> <span class="kw">use </span>std::assert_matches;
<a href=#450 id=450 data-nosnippet>450</a>
<a href=#451 id=451 data-nosnippet>451</a> <span class="kw">use </span><span class="kw">super</span>::AlterTableOperation;
<a href=#452 id=452 data-nosnippet>452</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#453 id=453 data-nosnippet>453</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#454 id=454 data-nosnippet>454</a> <span class="kw">use </span><span class="kw">crate</span>::statements::create::Json2Options;
<a href=#455 id=455 data-nosnippet>455</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#456 id=456 data-nosnippet>456</a>
<a href=#457 id=457 data-nosnippet>457</a> <span class="attr">#[test]
<a href=#458 id=458 data-nosnippet>458</a> </span><span class="kw">fn </span>test_display_alter() {
<a href=#459 id=459 data-nosnippet>459</a> <span class="kw">let </span>sql = <span class="string">r"ALTER DATABASE db SET 'a' = 'b', 'c' = 'd'"</span>;
<a href=#460 id=460 data-nosnippet>460</a> <span class="kw">let </span>stmts =
<a href=#461 id=461 data-nosnippet>461</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#462 id=462 data-nosnippet>462</a> .unwrap();
<a href=#463 id=463 data-nosnippet>463</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#464 id=464 data-nosnippet>464</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterDatabase { .. });
<a href=#465 id=465 data-nosnippet>465</a>
<a href=#466 id=466 data-nosnippet>466</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#467 id=467 data-nosnippet>467</a> Statement::AlterDatabase(set) =&gt; {
<a href=#468 id=468 data-nosnippet>468</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#469 id=469 data-nosnippet>469</a> <span class="macro">assert_eq!</span>(
<a href=#470 id=470 data-nosnippet>470</a> <span class="string">r#"
<a href=#471 id=471 data-nosnippet>471</a>ALTER DATABASE db SET 'a'='b','c'='d'"#</span>,
<a href=#472 id=472 data-nosnippet>472</a> <span class="kw-2">&amp;</span>new_sql
<a href=#473 id=473 data-nosnippet>473</a> );
<a href=#474 id=474 data-nosnippet>474</a> }
<a href=#475 id=475 data-nosnippet>475</a> <span class="kw">_ </span>=&gt; {
<a href=#476 id=476 data-nosnippet>476</a> <span class="macro">unreachable!</span>();
<a href=#477 id=477 data-nosnippet>477</a> }
<a href=#478 id=478 data-nosnippet>478</a> }
<a href=#479 id=479 data-nosnippet>479</a>
<a href=#480 id=480 data-nosnippet>480</a> <span class="kw">let </span>sql = <span class="string">r"ALTER DATABASE db UNSET 'a', 'c'"</span>;
<a href=#481 id=481 data-nosnippet>481</a> <span class="kw">let </span>stmts =
<a href=#482 id=482 data-nosnippet>482</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#483 id=483 data-nosnippet>483</a> .unwrap();
<a href=#484 id=484 data-nosnippet>484</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#485 id=485 data-nosnippet>485</a>
<a href=#486 id=486 data-nosnippet>486</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#487 id=487 data-nosnippet>487</a> Statement::AlterDatabase(set) =&gt; {
<a href=#488 id=488 data-nosnippet>488</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#489 id=489 data-nosnippet>489</a> <span class="macro">assert_eq!</span>(
<a href=#490 id=490 data-nosnippet>490</a> <span class="string">r#"
<a href=#491 id=491 data-nosnippet>491</a>ALTER DATABASE db UNSET 'a','c'"#</span>,
<a href=#492 id=492 data-nosnippet>492</a> <span class="kw-2">&amp;</span>new_sql
<a href=#493 id=493 data-nosnippet>493</a> );
<a href=#494 id=494 data-nosnippet>494</a> }
<a href=#495 id=495 data-nosnippet>495</a> <span class="kw">_ </span>=&gt; {
<a href=#496 id=496 data-nosnippet>496</a> <span class="macro">unreachable!</span>();
<a href=#497 id=497 data-nosnippet>497</a> }
<a href=#498 id=498 data-nosnippet>498</a> }
<a href=#499 id=499 data-nosnippet>499</a>
<a href=#500 id=500 data-nosnippet>500</a> <span class="kw">let </span>sql =
<a href=#501 id=501 data-nosnippet>501</a> <span class="string">r"alter table monitor add column app string default 'shop' primary key, add foo INT;"</span>;
<a href=#502 id=502 data-nosnippet>502</a> <span class="kw">let </span>stmts =
<a href=#503 id=503 data-nosnippet>503</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#504 id=504 data-nosnippet>504</a> .unwrap();
<a href=#505 id=505 data-nosnippet>505</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#506 id=506 data-nosnippet>506</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#507 id=507 data-nosnippet>507</a>
<a href=#508 id=508 data-nosnippet>508</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#509 id=509 data-nosnippet>509</a> Statement::AlterTable(set) =&gt; {
<a href=#510 id=510 data-nosnippet>510</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#511 id=511 data-nosnippet>511</a> <span class="macro">assert_eq!</span>(
<a href=#512 id=512 data-nosnippet>512</a> <span class="string">r#"
<a href=#513 id=513 data-nosnippet>513</a>ALTER TABLE monitor ADD COLUMN app STRING DEFAULT 'shop' PRIMARY KEY, ADD COLUMN foo INT"#</span>,
<a href=#514 id=514 data-nosnippet>514</a> <span class="kw-2">&amp;</span>new_sql
<a href=#515 id=515 data-nosnippet>515</a> );
<a href=#516 id=516 data-nosnippet>516</a> }
<a href=#517 id=517 data-nosnippet>517</a> <span class="kw">_ </span>=&gt; {
<a href=#518 id=518 data-nosnippet>518</a> <span class="macro">unreachable!</span>();
<a href=#519 id=519 data-nosnippet>519</a> }
<a href=#520 id=520 data-nosnippet>520</a> }
<a href=#521 id=521 data-nosnippet>521</a>
<a href=#522 id=522 data-nosnippet>522</a> <span class="kw">let </span>sql = <span class="string">r"alter table monitor modify column load_15 string;"</span>;
<a href=#523 id=523 data-nosnippet>523</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#524 id=524 data-nosnippet>524</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#525 id=525 data-nosnippet>525</a> .unwrap();
<a href=#526 id=526 data-nosnippet>526</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#527 id=527 data-nosnippet>527</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#528 id=528 data-nosnippet>528</a>
<a href=#529 id=529 data-nosnippet>529</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#530 id=530 data-nosnippet>530</a> Statement::AlterTable(set) =&gt; {
<a href=#531 id=531 data-nosnippet>531</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#532 id=532 data-nosnippet>532</a> <span class="macro">assert_eq!</span>(
<a href=#533 id=533 data-nosnippet>533</a> <span class="string">r#"
<a href=#534 id=534 data-nosnippet>534</a>ALTER TABLE monitor MODIFY COLUMN load_15 STRING"#</span>,
<a href=#535 id=535 data-nosnippet>535</a> <span class="kw-2">&amp;</span>new_sql
<a href=#536 id=536 data-nosnippet>536</a> );
<a href=#537 id=537 data-nosnippet>537</a> }
<a href=#538 id=538 data-nosnippet>538</a> <span class="kw">_ </span>=&gt; {
<a href=#539 id=539 data-nosnippet>539</a> <span class="macro">unreachable!</span>();
<a href=#540 id=540 data-nosnippet>540</a> }
<a href=#541 id=541 data-nosnippet>541</a> }
<a href=#542 id=542 data-nosnippet>542</a>
<a href=#543 id=543 data-nosnippet>543</a> <span class="kw">let </span>Statement::AlterTable(alter_table) = <span class="kw-2">&amp;mut </span>stmts[<span class="number">0</span>] <span class="kw">else </span>{
<a href=#544 id=544 data-nosnippet>544</a> <span class="macro">unreachable!</span>();
<a href=#545 id=545 data-nosnippet>545</a> };
<a href=#546 id=546 data-nosnippet>546</a> <span class="kw">let </span>AlterTableOperation::ModifyColumnType { json2_options, .. } =
<a href=#547 id=547 data-nosnippet>547</a> alter_table.alter_operation_mut()
<a href=#548 id=548 data-nosnippet>548</a> <span class="kw">else </span>{
<a href=#549 id=549 data-nosnippet>549</a> <span class="macro">unreachable!</span>();
<a href=#550 id=550 data-nosnippet>550</a> };
<a href=#551 id=551 data-nosnippet>551</a> <span class="kw-2">*</span>json2_options = <span class="prelude-val">Some</span>(Json2Options {
<a href=#552 id=552 data-nosnippet>552</a> max_auto_expanded_paths: <span class="prelude-val">Some</span>(<span class="number">1</span>),
<a href=#553 id=553 data-nosnippet>553</a> type_hints: <span class="macro">vec!</span>[],
<a href=#554 id=554 data-nosnippet>554</a> });
<a href=#555 id=555 data-nosnippet>555</a> <span class="macro">assert_eq!</span>(
<a href=#556 id=556 data-nosnippet>556</a> <span class="string">r#"ALTER TABLE monitor MODIFY COLUMN load_15 STRING(
<a href=#557 id=557 data-nosnippet>557</a> max_auto_expanded_paths = 1
<a href=#558 id=558 data-nosnippet>558</a> )"#</span>,
<a href=#559 id=559 data-nosnippet>559</a> alter_table.to_string()
<a href=#560 id=560 data-nosnippet>560</a> );
<a href=#561 id=561 data-nosnippet>561</a>
<a href=#562 id=562 data-nosnippet>562</a> <span class="kw">let </span>sql = <span class="string">r"alter table monitor drop column load_15;"</span>;
<a href=#563 id=563 data-nosnippet>563</a> <span class="kw">let </span>stmts =
<a href=#564 id=564 data-nosnippet>564</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#565 id=565 data-nosnippet>565</a> .unwrap();
<a href=#566 id=566 data-nosnippet>566</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#567 id=567 data-nosnippet>567</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#568 id=568 data-nosnippet>568</a>
<a href=#569 id=569 data-nosnippet>569</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#570 id=570 data-nosnippet>570</a> Statement::AlterTable(set) =&gt; {
<a href=#571 id=571 data-nosnippet>571</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#572 id=572 data-nosnippet>572</a> <span class="macro">assert_eq!</span>(
<a href=#573 id=573 data-nosnippet>573</a> <span class="string">r#"
<a href=#574 id=574 data-nosnippet>574</a>ALTER TABLE monitor DROP COLUMN load_15"#</span>,
<a href=#575 id=575 data-nosnippet>575</a> <span class="kw-2">&amp;</span>new_sql
<a href=#576 id=576 data-nosnippet>576</a> );
<a href=#577 id=577 data-nosnippet>577</a> }
<a href=#578 id=578 data-nosnippet>578</a> <span class="kw">_ </span>=&gt; {
<a href=#579 id=579 data-nosnippet>579</a> <span class="macro">unreachable!</span>();
<a href=#580 id=580 data-nosnippet>580</a> }
<a href=#581 id=581 data-nosnippet>581</a> }
<a href=#582 id=582 data-nosnippet>582</a>
<a href=#583 id=583 data-nosnippet>583</a> <span class="kw">let </span>sql = <span class="string">r"alter table monitor rename monitor_new;"</span>;
<a href=#584 id=584 data-nosnippet>584</a> <span class="kw">let </span>stmts =
<a href=#585 id=585 data-nosnippet>585</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#586 id=586 data-nosnippet>586</a> .unwrap();
<a href=#587 id=587 data-nosnippet>587</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#588 id=588 data-nosnippet>588</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#589 id=589 data-nosnippet>589</a>
<a href=#590 id=590 data-nosnippet>590</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#591 id=591 data-nosnippet>591</a> Statement::AlterTable(set) =&gt; {
<a href=#592 id=592 data-nosnippet>592</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#593 id=593 data-nosnippet>593</a> <span class="macro">assert_eq!</span>(
<a href=#594 id=594 data-nosnippet>594</a> <span class="string">r#"
<a href=#595 id=595 data-nosnippet>595</a>ALTER TABLE monitor RENAME monitor_new"#</span>,
<a href=#596 id=596 data-nosnippet>596</a> <span class="kw-2">&amp;</span>new_sql
<a href=#597 id=597 data-nosnippet>597</a> );
<a href=#598 id=598 data-nosnippet>598</a> }
<a href=#599 id=599 data-nosnippet>599</a> <span class="kw">_ </span>=&gt; {
<a href=#600 id=600 data-nosnippet>600</a> <span class="macro">unreachable!</span>();
<a href=#601 id=601 data-nosnippet>601</a> }
<a href=#602 id=602 data-nosnippet>602</a> }
<a href=#603 id=603 data-nosnippet>603</a>
<a href=#604 id=604 data-nosnippet>604</a> <span class="kw">let </span>sql = <span class="string">"ALTER TABLE monitor MODIFY COLUMN a SET FULLTEXT INDEX WITH(analyzer='English',case_sensitive='false',backend='bloom')"</span>;
<a href=#605 id=605 data-nosnippet>605</a> <span class="kw">let </span>stmts =
<a href=#606 id=606 data-nosnippet>606</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#607 id=607 data-nosnippet>607</a> .unwrap();
<a href=#608 id=608 data-nosnippet>608</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#609 id=609 data-nosnippet>609</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#610 id=610 data-nosnippet>610</a>
<a href=#611 id=611 data-nosnippet>611</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#612 id=612 data-nosnippet>612</a> Statement::AlterTable(set) =&gt; {
<a href=#613 id=613 data-nosnippet>613</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#614 id=614 data-nosnippet>614</a> <span class="macro">assert_eq!</span>(
<a href=#615 id=615 data-nosnippet>615</a> <span class="string">r#"
<a href=#616 id=616 data-nosnippet>616</a>ALTER TABLE monitor MODIFY COLUMN a SET FULLTEXT INDEX WITH(analyzer=English, case_sensitive=false, backend=bloom)"#</span>,
<a href=#617 id=617 data-nosnippet>617</a> <span class="kw-2">&amp;</span>new_sql
<a href=#618 id=618 data-nosnippet>618</a> );
<a href=#619 id=619 data-nosnippet>619</a> }
<a href=#620 id=620 data-nosnippet>620</a> <span class="kw">_ </span>=&gt; {
<a href=#621 id=621 data-nosnippet>621</a> <span class="macro">unreachable!</span>();
<a href=#622 id=622 data-nosnippet>622</a> }
<a href=#623 id=623 data-nosnippet>623</a> }
<a href=#624 id=624 data-nosnippet>624</a>
<a href=#625 id=625 data-nosnippet>625</a> <span class="kw">let </span>sql = <span class="string">"ALTER TABLE monitor MODIFY COLUMN a UNSET FULLTEXT INDEX"</span>;
<a href=#626 id=626 data-nosnippet>626</a> <span class="kw">let </span>stmts =
<a href=#627 id=627 data-nosnippet>627</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#628 id=628 data-nosnippet>628</a> .unwrap();
<a href=#629 id=629 data-nosnippet>629</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#630 id=630 data-nosnippet>630</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#631 id=631 data-nosnippet>631</a>
<a href=#632 id=632 data-nosnippet>632</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#633 id=633 data-nosnippet>633</a> Statement::AlterTable(set) =&gt; {
<a href=#634 id=634 data-nosnippet>634</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#635 id=635 data-nosnippet>635</a> <span class="macro">assert_eq!</span>(
<a href=#636 id=636 data-nosnippet>636</a> <span class="string">r#"
<a href=#637 id=637 data-nosnippet>637</a>ALTER TABLE monitor MODIFY COLUMN a UNSET FULLTEXT INDEX"#</span>,
<a href=#638 id=638 data-nosnippet>638</a> <span class="kw-2">&amp;</span>new_sql
<a href=#639 id=639 data-nosnippet>639</a> );
<a href=#640 id=640 data-nosnippet>640</a> }
<a href=#641 id=641 data-nosnippet>641</a> <span class="kw">_ </span>=&gt; {
<a href=#642 id=642 data-nosnippet>642</a> <span class="macro">unreachable!</span>();
<a href=#643 id=643 data-nosnippet>643</a> }
<a href=#644 id=644 data-nosnippet>644</a> }
<a href=#645 id=645 data-nosnippet>645</a>
<a href=#646 id=646 data-nosnippet>646</a> <span class="kw">let </span>sql = <span class="string">"ALTER TABLE monitor MODIFY COLUMN a SET INVERTED INDEX"</span>;
<a href=#647 id=647 data-nosnippet>647</a> <span class="kw">let </span>stmts =
<a href=#648 id=648 data-nosnippet>648</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#649 id=649 data-nosnippet>649</a> .unwrap();
<a href=#650 id=650 data-nosnippet>650</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#651 id=651 data-nosnippet>651</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#652 id=652 data-nosnippet>652</a>
<a href=#653 id=653 data-nosnippet>653</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#654 id=654 data-nosnippet>654</a> Statement::AlterTable(set) =&gt; {
<a href=#655 id=655 data-nosnippet>655</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#656 id=656 data-nosnippet>656</a> <span class="macro">assert_eq!</span>(
<a href=#657 id=657 data-nosnippet>657</a> <span class="string">r#"
<a href=#658 id=658 data-nosnippet>658</a>ALTER TABLE monitor MODIFY COLUMN a SET INVERTED INDEX"#</span>,
<a href=#659 id=659 data-nosnippet>659</a> <span class="kw-2">&amp;</span>new_sql
<a href=#660 id=660 data-nosnippet>660</a> );
<a href=#661 id=661 data-nosnippet>661</a> }
<a href=#662 id=662 data-nosnippet>662</a> <span class="kw">_ </span>=&gt; {
<a href=#663 id=663 data-nosnippet>663</a> <span class="macro">unreachable!</span>();
<a href=#664 id=664 data-nosnippet>664</a> }
<a href=#665 id=665 data-nosnippet>665</a> }
<a href=#666 id=666 data-nosnippet>666</a>
<a href=#667 id=667 data-nosnippet>667</a> <span class="kw">let </span>sql = <span class="string">"ALTER TABLE monitor MODIFY COLUMN a DROP DEFAULT"</span>;
<a href=#668 id=668 data-nosnippet>668</a> <span class="kw">let </span>stmts =
<a href=#669 id=669 data-nosnippet>669</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#670 id=670 data-nosnippet>670</a> .unwrap();
<a href=#671 id=671 data-nosnippet>671</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#672 id=672 data-nosnippet>672</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#673 id=673 data-nosnippet>673</a>
<a href=#674 id=674 data-nosnippet>674</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#675 id=675 data-nosnippet>675</a> Statement::AlterTable(set) =&gt; {
<a href=#676 id=676 data-nosnippet>676</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#677 id=677 data-nosnippet>677</a> <span class="macro">assert_eq!</span>(
<a href=#678 id=678 data-nosnippet>678</a> <span class="string">r#"
<a href=#679 id=679 data-nosnippet>679</a>ALTER TABLE monitor MODIFY COLUMN a DROP DEFAULT"#</span>,
<a href=#680 id=680 data-nosnippet>680</a> <span class="kw-2">&amp;</span>new_sql
<a href=#681 id=681 data-nosnippet>681</a> );
<a href=#682 id=682 data-nosnippet>682</a> }
<a href=#683 id=683 data-nosnippet>683</a> <span class="kw">_ </span>=&gt; {
<a href=#684 id=684 data-nosnippet>684</a> <span class="macro">unreachable!</span>();
<a href=#685 id=685 data-nosnippet>685</a> }
<a href=#686 id=686 data-nosnippet>686</a> }
<a href=#687 id=687 data-nosnippet>687</a>
<a href=#688 id=688 data-nosnippet>688</a> <span class="kw">let </span>sql = <span class="string">"ALTER TABLE monitor MODIFY COLUMN a SET DEFAULT 'default_for_a'"</span>;
<a href=#689 id=689 data-nosnippet>689</a> <span class="kw">let </span>stmts =
<a href=#690 id=690 data-nosnippet>690</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#691 id=691 data-nosnippet>691</a> .unwrap();
<a href=#692 id=692 data-nosnippet>692</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#693 id=693 data-nosnippet>693</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::AlterTable { .. });
<a href=#694 id=694 data-nosnippet>694</a>
<a href=#695 id=695 data-nosnippet>695</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#696 id=696 data-nosnippet>696</a> Statement::AlterTable(set) =&gt; {
<a href=#697 id=697 data-nosnippet>697</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#698 id=698 data-nosnippet>698</a> <span class="macro">assert_eq!</span>(
<a href=#699 id=699 data-nosnippet>699</a> <span class="string">r#"
<a href=#700 id=700 data-nosnippet>700</a>ALTER TABLE monitor MODIFY COLUMN a SET DEFAULT 'default_for_a'"#</span>,
<a href=#701 id=701 data-nosnippet>701</a> <span class="kw-2">&amp;</span>new_sql
<a href=#702 id=702 data-nosnippet>702</a> );
<a href=#703 id=703 data-nosnippet>703</a> }
<a href=#704 id=704 data-nosnippet>704</a> <span class="kw">_ </span>=&gt; {
<a href=#705 id=705 data-nosnippet>705</a> <span class="macro">unreachable!</span>();
<a href=#706 id=706 data-nosnippet>706</a> }
<a href=#707 id=707 data-nosnippet>707</a> }
<a href=#708 id=708 data-nosnippet>708</a> }
<a href=#709 id=709 data-nosnippet>709</a>}
</code></pre></div></section></main></body></html>
+68
View File
@@ -0,0 +1,68 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/comment.rs`."><title>comment.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>comment.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::{<span class="self">self</span>, Display, Formatter};
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::ast::{Ident, ObjectName};
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="doccomment">/// Represents a SQL COMMENT statement for adding or removing comments on database objects.
<a href=#23 id=23 data-nosnippet>23</a>///
<a href=#24 id=24 data-nosnippet>24</a>/// # Examples
<a href=#25 id=25 data-nosnippet>25</a>///
<a href=#26 id=26 data-nosnippet>26</a>/// ```sql
<a href=#27 id=27 data-nosnippet>27</a>/// COMMENT ON TABLE my_table IS 'This is a table comment';
<a href=#28 id=28 data-nosnippet>28</a>/// COMMENT ON COLUMN my_table.my_column IS 'This is a column comment';
<a href=#29 id=29 data-nosnippet>29</a>/// COMMENT ON FLOW my_flow IS NULL;
<a href=#30 id=30 data-nosnippet>30</a>/// ```
<a href=#31 id=31 data-nosnippet>31</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#32 id=32 data-nosnippet>32</a></span><span class="kw">pub struct </span>Comment {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">pub </span>object: CommentObject,
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">pub </span>comment: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#35 id=35 data-nosnippet>35</a>}
<a href=#36 id=36 data-nosnippet>36</a>
<a href=#37 id=37 data-nosnippet>37</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#38 id=38 data-nosnippet>38</a></span><span class="kw">pub enum </span>CommentObject {
<a href=#39 id=39 data-nosnippet>39</a> Table(ObjectName),
<a href=#40 id=40 data-nosnippet>40</a> Column { table: ObjectName, column: Ident },
<a href=#41 id=41 data-nosnippet>41</a> Flow(ObjectName),
<a href=#42 id=42 data-nosnippet>42</a>}
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a><span class="kw">impl </span>Display <span class="kw">for </span>Comment {
<a href=#45 id=45 data-nosnippet>45</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#46 id=46 data-nosnippet>46</a> <span class="macro">write!</span>(f, <span class="string">"COMMENT ON {} IS "</span>, <span class="self">self</span>.object)<span class="question-mark">?</span>;
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.comment {
<a href=#48 id=48 data-nosnippet>48</a> <span class="prelude-val">Some</span>(comment) =&gt; {
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">let </span>escaped = comment.replace(<span class="string">'\''</span>, <span class="string">"''"</span>);
<a href=#50 id=50 data-nosnippet>50</a> <span class="macro">write!</span>(f, <span class="string">"'{}'"</span>, escaped)
<a href=#51 id=51 data-nosnippet>51</a> }
<a href=#52 id=52 data-nosnippet>52</a> <span class="prelude-val">None </span>=&gt; f.write_str(<span class="string">"NULL"</span>),
<a href=#53 id=53 data-nosnippet>53</a> }
<a href=#54 id=54 data-nosnippet>54</a> }
<a href=#55 id=55 data-nosnippet>55</a>}
<a href=#56 id=56 data-nosnippet>56</a>
<a href=#57 id=57 data-nosnippet>57</a><span class="kw">impl </span>Display <span class="kw">for </span>CommentObject {
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#60 id=60 data-nosnippet>60</a> CommentObject::Table(name) =&gt; <span class="macro">write!</span>(f, <span class="string">"TABLE {}"</span>, name),
<a href=#61 id=61 data-nosnippet>61</a> CommentObject::Column { table, column } =&gt; {
<a href=#62 id=62 data-nosnippet>62</a> <span class="macro">write!</span>(f, <span class="string">"COLUMN {}.{}"</span>, table, column)
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a> CommentObject::Flow(name) =&gt; <span class="macro">write!</span>(f, <span class="string">"FLOW {}"</span>, name),
<a href=#65 id=65 data-nosnippet>65</a> }
<a href=#66 id=66 data-nosnippet>66</a> }
<a href=#67 id=67 data-nosnippet>67</a>}
</code></pre></div></section></main></body></html>
+298
View File
@@ -0,0 +1,298 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/copy.rs`."><title>copy.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>copy.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::ObjectName;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::OptionMap;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#25 id=25 data-nosnippet>25</a></span><span class="kw">pub enum </span>Copy {
<a href=#26 id=26 data-nosnippet>26</a> CopyTable(CopyTable),
<a href=#27 id=27 data-nosnippet>27</a> CopyDatabase(CopyDatabase),
<a href=#28 id=28 data-nosnippet>28</a> CopyQueryTo(CopyQueryTo),
<a href=#29 id=29 data-nosnippet>29</a>}
<a href=#30 id=30 data-nosnippet>30</a>
<a href=#31 id=31 data-nosnippet>31</a><span class="kw">impl </span>Display <span class="kw">for </span>Copy {
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#34 id=34 data-nosnippet>34</a> Copy::CopyTable(s) =&gt; s.fmt(f),
<a href=#35 id=35 data-nosnippet>35</a> Copy::CopyDatabase(s) =&gt; s.fmt(f),
<a href=#36 id=36 data-nosnippet>36</a> Copy::CopyQueryTo(s) =&gt; s.fmt(f),
<a href=#37 id=37 data-nosnippet>37</a> }
<a href=#38 id=38 data-nosnippet>38</a> }
<a href=#39 id=39 data-nosnippet>39</a>}
<a href=#40 id=40 data-nosnippet>40</a>
<a href=#41 id=41 data-nosnippet>41</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#42 id=42 data-nosnippet>42</a></span><span class="kw">pub struct </span>CopyQueryTo {
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw">pub </span>query: Box&lt;Statement&gt;,
<a href=#44 id=44 data-nosnippet>44</a> <span class="kw">pub </span>arg: CopyQueryToArgument,
<a href=#45 id=45 data-nosnippet>45</a>}
<a href=#46 id=46 data-nosnippet>46</a>
<a href=#47 id=47 data-nosnippet>47</a><span class="kw">impl </span>Display <span class="kw">for </span>CopyQueryTo {
<a href=#48 id=48 data-nosnippet>48</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#49 id=49 data-nosnippet>49</a> <span class="macro">write!</span>(f, <span class="string">"COPY ({}) TO {}"</span>, <span class="self">self</span>.query, <span class="self">self</span>.arg.location)<span class="question-mark">?</span>;
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">if </span>!<span class="self">self</span>.arg.with.is_empty() {
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">let </span>options = <span class="self">self</span>.arg.with.kv_pairs();
<a href=#52 id=52 data-nosnippet>52</a> <span class="macro">write!</span>(f, <span class="string">" WITH ({})"</span>, options.join(<span class="string">", "</span>))<span class="question-mark">?</span>;
<a href=#53 id=53 data-nosnippet>53</a> }
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">if </span>!<span class="self">self</span>.arg.connection.is_empty() {
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">let </span>options = <span class="self">self</span>.arg.connection.kv_pairs();
<a href=#56 id=56 data-nosnippet>56</a> <span class="macro">write!</span>(f, <span class="string">" CONNECTION ({})"</span>, options.join(<span class="string">", "</span>))<span class="question-mark">?</span>;
<a href=#57 id=57 data-nosnippet>57</a> }
<a href=#58 id=58 data-nosnippet>58</a> <span class="prelude-val">Ok</span>(())
<a href=#59 id=59 data-nosnippet>59</a> }
<a href=#60 id=60 data-nosnippet>60</a>}
<a href=#61 id=61 data-nosnippet>61</a>
<a href=#62 id=62 data-nosnippet>62</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#63 id=63 data-nosnippet>63</a></span><span class="kw">pub enum </span>CopyTable {
<a href=#64 id=64 data-nosnippet>64</a> To(CopyTableArgument),
<a href=#65 id=65 data-nosnippet>65</a> From(CopyTableArgument),
<a href=#66 id=66 data-nosnippet>66</a>}
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a><span class="kw">impl </span>Display <span class="kw">for </span>CopyTable {
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#70 id=70 data-nosnippet>70</a> <span class="macro">write!</span>(f, <span class="string">"COPY "</span>)<span class="question-mark">?</span>;
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">let </span>(with, connection) = <span class="kw">match </span><span class="self">self </span>{
<a href=#72 id=72 data-nosnippet>72</a> CopyTable::To(args) =&gt; {
<a href=#73 id=73 data-nosnippet>73</a> <span class="macro">write!</span>(f, <span class="string">"{} TO {}"</span>, args.table_name, args.location)<span class="question-mark">?</span>;
<a href=#74 id=74 data-nosnippet>74</a> (<span class="kw-2">&amp;</span>args.with, <span class="kw-2">&amp;</span>args.connection)
<a href=#75 id=75 data-nosnippet>75</a> }
<a href=#76 id=76 data-nosnippet>76</a> CopyTable::From(args) =&gt; {
<a href=#77 id=77 data-nosnippet>77</a> <span class="macro">write!</span>(f, <span class="string">"{} FROM {}"</span>, args.table_name, args.location)<span class="question-mark">?</span>;
<a href=#78 id=78 data-nosnippet>78</a> (<span class="kw-2">&amp;</span>args.with, <span class="kw-2">&amp;</span>args.connection)
<a href=#79 id=79 data-nosnippet>79</a> }
<a href=#80 id=80 data-nosnippet>80</a> };
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">if </span>!with.is_empty() {
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">let </span>options = with.kv_pairs();
<a href=#83 id=83 data-nosnippet>83</a> <span class="macro">write!</span>(f, <span class="string">" WITH ({})"</span>, options.join(<span class="string">", "</span>))<span class="question-mark">?</span>;
<a href=#84 id=84 data-nosnippet>84</a> }
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">if </span>!connection.is_empty() {
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">let </span>options = connection.kv_pairs();
<a href=#87 id=87 data-nosnippet>87</a> <span class="macro">write!</span>(f, <span class="string">" CONNECTION ({})"</span>, options.join(<span class="string">", "</span>))<span class="question-mark">?</span>;
<a href=#88 id=88 data-nosnippet>88</a> }
<a href=#89 id=89 data-nosnippet>89</a> <span class="prelude-val">Ok</span>(())
<a href=#90 id=90 data-nosnippet>90</a> }
<a href=#91 id=91 data-nosnippet>91</a>}
<a href=#92 id=92 data-nosnippet>92</a>
<a href=#93 id=93 data-nosnippet>93</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#94 id=94 data-nosnippet>94</a></span><span class="kw">pub enum </span>CopyDatabase {
<a href=#95 id=95 data-nosnippet>95</a> To(CopyDatabaseArgument),
<a href=#96 id=96 data-nosnippet>96</a> From(CopyDatabaseArgument),
<a href=#97 id=97 data-nosnippet>97</a>}
<a href=#98 id=98 data-nosnippet>98</a>
<a href=#99 id=99 data-nosnippet>99</a><span class="kw">impl </span>Display <span class="kw">for </span>CopyDatabase {
<a href=#100 id=100 data-nosnippet>100</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#101 id=101 data-nosnippet>101</a> <span class="macro">write!</span>(f, <span class="string">"COPY DATABASE "</span>)<span class="question-mark">?</span>;
<a href=#102 id=102 data-nosnippet>102</a> <span class="kw">let </span>(with, connection) = <span class="kw">match </span><span class="self">self </span>{
<a href=#103 id=103 data-nosnippet>103</a> CopyDatabase::To(args) =&gt; {
<a href=#104 id=104 data-nosnippet>104</a> <span class="macro">write!</span>(f, <span class="string">"{} TO {}"</span>, args.database_name, args.location)<span class="question-mark">?</span>;
<a href=#105 id=105 data-nosnippet>105</a> (<span class="kw-2">&amp;</span>args.with, <span class="kw-2">&amp;</span>args.connection)
<a href=#106 id=106 data-nosnippet>106</a> }
<a href=#107 id=107 data-nosnippet>107</a> CopyDatabase::From(args) =&gt; {
<a href=#108 id=108 data-nosnippet>108</a> <span class="macro">write!</span>(f, <span class="string">"{} FROM {}"</span>, args.database_name, args.location)<span class="question-mark">?</span>;
<a href=#109 id=109 data-nosnippet>109</a> (<span class="kw-2">&amp;</span>args.with, <span class="kw-2">&amp;</span>args.connection)
<a href=#110 id=110 data-nosnippet>110</a> }
<a href=#111 id=111 data-nosnippet>111</a> };
<a href=#112 id=112 data-nosnippet>112</a> <span class="kw">if </span>!with.is_empty() {
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">let </span>options = with.kv_pairs();
<a href=#114 id=114 data-nosnippet>114</a> <span class="macro">write!</span>(f, <span class="string">" WITH ({})"</span>, options.join(<span class="string">", "</span>))<span class="question-mark">?</span>;
<a href=#115 id=115 data-nosnippet>115</a> }
<a href=#116 id=116 data-nosnippet>116</a> <span class="kw">if </span>!connection.is_empty() {
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">let </span>options = connection.kv_pairs();
<a href=#118 id=118 data-nosnippet>118</a> <span class="macro">write!</span>(f, <span class="string">" CONNECTION ({})"</span>, options.join(<span class="string">", "</span>))<span class="question-mark">?</span>;
<a href=#119 id=119 data-nosnippet>119</a> }
<a href=#120 id=120 data-nosnippet>120</a> <span class="prelude-val">Ok</span>(())
<a href=#121 id=121 data-nosnippet>121</a> }
<a href=#122 id=122 data-nosnippet>122</a>}
<a href=#123 id=123 data-nosnippet>123</a>
<a href=#124 id=124 data-nosnippet>124</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#125 id=125 data-nosnippet>125</a></span><span class="kw">pub struct </span>CopyDatabaseArgument {
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">pub </span>database_name: ObjectName,
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">pub </span>with: OptionMap,
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">pub </span>connection: OptionMap,
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">pub </span>location: String,
<a href=#130 id=130 data-nosnippet>130</a>}
<a href=#131 id=131 data-nosnippet>131</a>
<a href=#132 id=132 data-nosnippet>132</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#133 id=133 data-nosnippet>133</a></span><span class="kw">pub struct </span>CopyTableArgument {
<a href=#134 id=134 data-nosnippet>134</a> <span class="kw">pub </span>table_name: ObjectName,
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">pub </span>with: OptionMap,
<a href=#136 id=136 data-nosnippet>136</a> <span class="kw">pub </span>connection: OptionMap,
<a href=#137 id=137 data-nosnippet>137</a> <span class="doccomment">/// Copy tbl [To|From] 'location'.
<a href=#138 id=138 data-nosnippet>138</a> </span><span class="kw">pub </span>location: String,
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw">pub </span>limit: <span class="prelude-ty">Option</span>&lt;u64&gt;,
<a href=#140 id=140 data-nosnippet>140</a>}
<a href=#141 id=141 data-nosnippet>141</a>
<a href=#142 id=142 data-nosnippet>142</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#143 id=143 data-nosnippet>143</a></span><span class="kw">pub struct </span>CopyQueryToArgument {
<a href=#144 id=144 data-nosnippet>144</a> <span class="kw">pub </span>with: OptionMap,
<a href=#145 id=145 data-nosnippet>145</a> <span class="kw">pub </span>connection: OptionMap,
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">pub </span>location: String,
<a href=#147 id=147 data-nosnippet>147</a>}
<a href=#148 id=148 data-nosnippet>148</a>
<a href=#149 id=149 data-nosnippet>149</a><span class="attr">#[cfg(test)]
<a href=#150 id=150 data-nosnippet>150</a></span><span class="kw">impl </span>CopyTableArgument {
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw">pub fn </span>format(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;String&gt; {
<a href=#152 id=152 data-nosnippet>152</a> <span class="self">self</span>.with
<a href=#153 id=153 data-nosnippet>153</a> .get(common_datasource::file_format::FORMAT_TYPE)
<a href=#154 id=154 data-nosnippet>154</a> .map(|v| v.to_string())
<a href=#155 id=155 data-nosnippet>155</a> .or_else(|| <span class="prelude-val">Some</span>(<span class="string">"PARQUET"</span>.to_string()))
<a href=#156 id=156 data-nosnippet>156</a> }
<a href=#157 id=157 data-nosnippet>157</a>
<a href=#158 id=158 data-nosnippet>158</a> <span class="kw">pub fn </span>pattern(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;String&gt; {
<a href=#159 id=159 data-nosnippet>159</a> <span class="self">self</span>.with
<a href=#160 id=160 data-nosnippet>160</a> .get(common_datasource::file_format::FILE_PATTERN)
<a href=#161 id=161 data-nosnippet>161</a> .map(|v| v.to_string())
<a href=#162 id=162 data-nosnippet>162</a> }
<a href=#163 id=163 data-nosnippet>163</a>}
<a href=#164 id=164 data-nosnippet>164</a>
<a href=#165 id=165 data-nosnippet>165</a><span class="attr">#[cfg(test)]
<a href=#166 id=166 data-nosnippet>166</a></span><span class="kw">mod </span>tests {
<a href=#167 id=167 data-nosnippet>167</a> <span class="kw">use </span>std::assert_matches;
<a href=#168 id=168 data-nosnippet>168</a>
<a href=#169 id=169 data-nosnippet>169</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#170 id=170 data-nosnippet>170</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#172 id=172 data-nosnippet>172</a>
<a href=#173 id=173 data-nosnippet>173</a> <span class="attr">#[test]
<a href=#174 id=174 data-nosnippet>174</a> </span><span class="kw">fn </span>test_display_copy_from_tb() {
<a href=#175 id=175 data-nosnippet>175</a> <span class="kw">let </span>sql = <span class="string">r"copy tbl from 's3://my-bucket/data.parquet'
<a href=#176 id=176 data-nosnippet>176</a> with (format = 'parquet', pattern = '.*parquet.*')
<a href=#177 id=177 data-nosnippet>177</a> connection(region = 'us-west-2', secret_access_key = '12345678');"</span>;
<a href=#178 id=178 data-nosnippet>178</a> <span class="kw">let </span>stmts =
<a href=#179 id=179 data-nosnippet>179</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#180 id=180 data-nosnippet>180</a> .unwrap();
<a href=#181 id=181 data-nosnippet>181</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#182 id=182 data-nosnippet>182</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::Copy { .. });
<a href=#183 id=183 data-nosnippet>183</a>
<a href=#184 id=184 data-nosnippet>184</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#185 id=185 data-nosnippet>185</a> Statement::Copy(copy) =&gt; {
<a href=#186 id=186 data-nosnippet>186</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"{}"</span>, copy);
<a href=#187 id=187 data-nosnippet>187</a> <span class="macro">assert_eq!</span>(
<a href=#188 id=188 data-nosnippet>188</a> <span class="string">r#"COPY tbl FROM s3://my-bucket/data.parquet WITH (format = 'parquet', pattern = '.*parquet.*') CONNECTION (region = 'us-west-2', secret_access_key = '******')"#</span>,
<a href=#189 id=189 data-nosnippet>189</a> <span class="kw-2">&amp;</span>new_sql
<a href=#190 id=190 data-nosnippet>190</a> );
<a href=#191 id=191 data-nosnippet>191</a> }
<a href=#192 id=192 data-nosnippet>192</a> <span class="kw">_ </span>=&gt; {
<a href=#193 id=193 data-nosnippet>193</a> <span class="macro">unreachable!</span>();
<a href=#194 id=194 data-nosnippet>194</a> }
<a href=#195 id=195 data-nosnippet>195</a> }
<a href=#196 id=196 data-nosnippet>196</a> }
<a href=#197 id=197 data-nosnippet>197</a>
<a href=#198 id=198 data-nosnippet>198</a> <span class="attr">#[test]
<a href=#199 id=199 data-nosnippet>199</a> </span><span class="kw">fn </span>test_display_copy_to_tb() {
<a href=#200 id=200 data-nosnippet>200</a> <span class="kw">let </span>sql = <span class="string">r"copy tbl to 's3://my-bucket/data.parquet'
<a href=#201 id=201 data-nosnippet>201</a> with (format = 'parquet', pattern = '.*parquet.*')
<a href=#202 id=202 data-nosnippet>202</a> connection(region = 'us-west-2', secret_access_key = '12345678');"</span>;
<a href=#203 id=203 data-nosnippet>203</a> <span class="kw">let </span>stmts =
<a href=#204 id=204 data-nosnippet>204</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#205 id=205 data-nosnippet>205</a> .unwrap();
<a href=#206 id=206 data-nosnippet>206</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#207 id=207 data-nosnippet>207</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::Copy { .. });
<a href=#208 id=208 data-nosnippet>208</a>
<a href=#209 id=209 data-nosnippet>209</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#210 id=210 data-nosnippet>210</a> Statement::Copy(copy) =&gt; {
<a href=#211 id=211 data-nosnippet>211</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"{}"</span>, copy);
<a href=#212 id=212 data-nosnippet>212</a> <span class="macro">assert_eq!</span>(
<a href=#213 id=213 data-nosnippet>213</a> <span class="string">r#"COPY tbl TO s3://my-bucket/data.parquet WITH (format = 'parquet', pattern = '.*parquet.*') CONNECTION (region = 'us-west-2', secret_access_key = '******')"#</span>,
<a href=#214 id=214 data-nosnippet>214</a> <span class="kw-2">&amp;</span>new_sql
<a href=#215 id=215 data-nosnippet>215</a> );
<a href=#216 id=216 data-nosnippet>216</a> }
<a href=#217 id=217 data-nosnippet>217</a> <span class="kw">_ </span>=&gt; {
<a href=#218 id=218 data-nosnippet>218</a> <span class="macro">unreachable!</span>();
<a href=#219 id=219 data-nosnippet>219</a> }
<a href=#220 id=220 data-nosnippet>220</a> }
<a href=#221 id=221 data-nosnippet>221</a> }
<a href=#222 id=222 data-nosnippet>222</a>
<a href=#223 id=223 data-nosnippet>223</a> <span class="attr">#[test]
<a href=#224 id=224 data-nosnippet>224</a> </span><span class="kw">fn </span>test_display_copy_from_db() {
<a href=#225 id=225 data-nosnippet>225</a> <span class="kw">let </span>sql = <span class="string">r"copy database db1 from 's3://my-bucket/data.parquet'
<a href=#226 id=226 data-nosnippet>226</a> with (format = 'parquet', pattern = '.*parquet.*')
<a href=#227 id=227 data-nosnippet>227</a> connection(region = 'us-west-2', secret_access_key = '12345678');"</span>;
<a href=#228 id=228 data-nosnippet>228</a> <span class="kw">let </span>stmts =
<a href=#229 id=229 data-nosnippet>229</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#230 id=230 data-nosnippet>230</a> .unwrap();
<a href=#231 id=231 data-nosnippet>231</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#232 id=232 data-nosnippet>232</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::Copy { .. });
<a href=#233 id=233 data-nosnippet>233</a>
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#235 id=235 data-nosnippet>235</a> Statement::Copy(copy) =&gt; {
<a href=#236 id=236 data-nosnippet>236</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"{}"</span>, copy);
<a href=#237 id=237 data-nosnippet>237</a> <span class="macro">assert_eq!</span>(
<a href=#238 id=238 data-nosnippet>238</a> <span class="string">r#"COPY DATABASE db1 FROM s3://my-bucket/data.parquet WITH (format = 'parquet', pattern = '.*parquet.*') CONNECTION (region = 'us-west-2', secret_access_key = '******')"#</span>,
<a href=#239 id=239 data-nosnippet>239</a> <span class="kw-2">&amp;</span>new_sql
<a href=#240 id=240 data-nosnippet>240</a> );
<a href=#241 id=241 data-nosnippet>241</a> }
<a href=#242 id=242 data-nosnippet>242</a> <span class="kw">_ </span>=&gt; {
<a href=#243 id=243 data-nosnippet>243</a> <span class="macro">unreachable!</span>();
<a href=#244 id=244 data-nosnippet>244</a> }
<a href=#245 id=245 data-nosnippet>245</a> }
<a href=#246 id=246 data-nosnippet>246</a> }
<a href=#247 id=247 data-nosnippet>247</a>
<a href=#248 id=248 data-nosnippet>248</a> <span class="attr">#[test]
<a href=#249 id=249 data-nosnippet>249</a> </span><span class="kw">fn </span>test_display_copy_to_db() {
<a href=#250 id=250 data-nosnippet>250</a> <span class="kw">let </span>sql = <span class="string">r"copy database db1 to 's3://my-bucket/data.parquet'
<a href=#251 id=251 data-nosnippet>251</a> with (format = 'parquet', pattern = '.*parquet.*')
<a href=#252 id=252 data-nosnippet>252</a> connection(region = 'us-west-2', secret_access_key = '12345678');"</span>;
<a href=#253 id=253 data-nosnippet>253</a> <span class="kw">let </span>stmts =
<a href=#254 id=254 data-nosnippet>254</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#255 id=255 data-nosnippet>255</a> .unwrap();
<a href=#256 id=256 data-nosnippet>256</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#257 id=257 data-nosnippet>257</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::Copy { .. });
<a href=#258 id=258 data-nosnippet>258</a>
<a href=#259 id=259 data-nosnippet>259</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#260 id=260 data-nosnippet>260</a> Statement::Copy(copy) =&gt; {
<a href=#261 id=261 data-nosnippet>261</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"{}"</span>, copy);
<a href=#262 id=262 data-nosnippet>262</a> <span class="macro">assert_eq!</span>(
<a href=#263 id=263 data-nosnippet>263</a> <span class="string">r#"COPY DATABASE db1 TO s3://my-bucket/data.parquet WITH (format = 'parquet', pattern = '.*parquet.*') CONNECTION (region = 'us-west-2', secret_access_key = '******')"#</span>,
<a href=#264 id=264 data-nosnippet>264</a> <span class="kw-2">&amp;</span>new_sql
<a href=#265 id=265 data-nosnippet>265</a> );
<a href=#266 id=266 data-nosnippet>266</a> }
<a href=#267 id=267 data-nosnippet>267</a> <span class="kw">_ </span>=&gt; {
<a href=#268 id=268 data-nosnippet>268</a> <span class="macro">unreachable!</span>();
<a href=#269 id=269 data-nosnippet>269</a> }
<a href=#270 id=270 data-nosnippet>270</a> }
<a href=#271 id=271 data-nosnippet>271</a> }
<a href=#272 id=272 data-nosnippet>272</a>
<a href=#273 id=273 data-nosnippet>273</a> <span class="attr">#[test]
<a href=#274 id=274 data-nosnippet>274</a> </span><span class="kw">fn </span>test_display_copy_query_to() {
<a href=#275 id=275 data-nosnippet>275</a> <span class="kw">let </span>sql = <span class="string">r"copy (SELECT * FROM tbl WHERE ts &gt; 10) to 's3://my-bucket/data.parquet'
<a href=#276 id=276 data-nosnippet>276</a> with (format = 'parquet', pattern = '.*parquet.*')
<a href=#277 id=277 data-nosnippet>277</a> connection(region = 'us-west-2', secret_access_key = '12345678');"</span>;
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">let </span>stmts =
<a href=#279 id=279 data-nosnippet>279</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#280 id=280 data-nosnippet>280</a> .unwrap();
<a href=#281 id=281 data-nosnippet>281</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#282 id=282 data-nosnippet>282</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::Copy { .. });
<a href=#283 id=283 data-nosnippet>283</a>
<a href=#284 id=284 data-nosnippet>284</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#285 id=285 data-nosnippet>285</a> Statement::Copy(copy) =&gt; {
<a href=#286 id=286 data-nosnippet>286</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"{}"</span>, copy);
<a href=#287 id=287 data-nosnippet>287</a> <span class="macro">assert_eq!</span>(
<a href=#288 id=288 data-nosnippet>288</a> <span class="string">r#"COPY (SELECT * FROM tbl WHERE ts &gt; 10) TO s3://my-bucket/data.parquet WITH (format = 'parquet', pattern = '.*parquet.*') CONNECTION (region = 'us-west-2', secret_access_key = '******')"#</span>,
<a href=#289 id=289 data-nosnippet>289</a> <span class="kw-2">&amp;</span>new_sql
<a href=#290 id=290 data-nosnippet>290</a> );
<a href=#291 id=291 data-nosnippet>291</a> }
<a href=#292 id=292 data-nosnippet>292</a> <span class="kw">_ </span>=&gt; {
<a href=#293 id=293 data-nosnippet>293</a> <span class="macro">unreachable!</span>();
<a href=#294 id=294 data-nosnippet>294</a> }
<a href=#295 id=295 data-nosnippet>295</a> }
<a href=#296 id=296 data-nosnippet>296</a> }
<a href=#297 id=297 data-nosnippet>297</a>}
</code></pre></div></section></main></body></html>
File diff suppressed because it is too large Load Diff
+62
View File
@@ -0,0 +1,62 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/cursor.rs`."><title>cursor.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>cursor.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::ObjectName;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::query::Query;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// Represents a DECLARE CURSOR statement
<a href=#24 id=24 data-nosnippet>24</a>///
<a href=#25 id=25 data-nosnippet>25</a>/// This statement will carry a SQL query
<a href=#26 id=26 data-nosnippet>26</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#27 id=27 data-nosnippet>27</a></span><span class="kw">pub struct </span>DeclareCursor {
<a href=#28 id=28 data-nosnippet>28</a> <span class="kw">pub </span>cursor_name: ObjectName,
<a href=#29 id=29 data-nosnippet>29</a> <span class="kw">pub </span>query: Box&lt;Query&gt;,
<a href=#30 id=30 data-nosnippet>30</a>}
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">impl </span>Display <span class="kw">for </span>DeclareCursor {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#34 id=34 data-nosnippet>34</a> <span class="macro">write!</span>(f, <span class="string">"DECLARE {} CURSOR FOR {}"</span>, <span class="self">self</span>.cursor_name, <span class="self">self</span>.query)
<a href=#35 id=35 data-nosnippet>35</a> }
<a href=#36 id=36 data-nosnippet>36</a>}
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a><span class="doccomment">/// Represents a FETCH FROM cursor statement
<a href=#39 id=39 data-nosnippet>39</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#40 id=40 data-nosnippet>40</a></span><span class="kw">pub struct </span>FetchCursor {
<a href=#41 id=41 data-nosnippet>41</a> <span class="kw">pub </span>cursor_name: ObjectName,
<a href=#42 id=42 data-nosnippet>42</a> <span class="kw">pub </span>fetch_size: u64,
<a href=#43 id=43 data-nosnippet>43</a>}
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a><span class="kw">impl </span>Display <span class="kw">for </span>FetchCursor {
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#47 id=47 data-nosnippet>47</a> <span class="macro">write!</span>(f, <span class="string">"FETCH {} FROM {}"</span>, <span class="self">self</span>.fetch_size, <span class="self">self</span>.cursor_name)
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a>}
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a><span class="doccomment">/// Represents a CLOSE cursor statement
<a href=#52 id=52 data-nosnippet>52</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#53 id=53 data-nosnippet>53</a></span><span class="kw">pub struct </span>CloseCursor {
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">pub </span>cursor_name: ObjectName,
<a href=#55 id=55 data-nosnippet>55</a>}
<a href=#56 id=56 data-nosnippet>56</a>
<a href=#57 id=57 data-nosnippet>57</a><span class="kw">impl </span>Display <span class="kw">for </span>CloseCursor {
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#59 id=59 data-nosnippet>59</a> <span class="macro">write!</span>(f, <span class="string">"CLOSE {}"</span>, <span class="self">self</span>.cursor_name)
<a href=#60 id=60 data-nosnippet>60</a> }
<a href=#61 id=61 data-nosnippet>61</a>}
</code></pre></div></section></main></body></html>
+23
View File
@@ -0,0 +1,23 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/delete.rs`."><title>delete.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>delete.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>serde::Serialize;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::Statement;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#20 id=20 data-nosnippet>20</a></span><span class="kw">pub struct </span>Delete {
<a href=#21 id=21 data-nosnippet>21</a> <span class="kw">pub </span>inner: Statement,
<a href=#22 id=22 data-nosnippet>22</a>}
</code></pre></div></section></main></body></html>
+144
View File
@@ -0,0 +1,144 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/describe.rs`."><title>describe.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>describe.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::ObjectName;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="doccomment">/// SQL structure for `DESCRIBE TABLE`.
<a href=#22 id=22 data-nosnippet>22</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#23 id=23 data-nosnippet>23</a></span><span class="kw">pub struct </span>DescribeTable {
<a href=#24 id=24 data-nosnippet>24</a> name: ObjectName,
<a href=#25 id=25 data-nosnippet>25</a>}
<a href=#26 id=26 data-nosnippet>26</a>
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">impl </span>DescribeTable {
<a href=#28 id=28 data-nosnippet>28</a> <span class="doccomment">/// Creates a statement for `DESCRIBE TABLE`
<a href=#29 id=29 data-nosnippet>29</a> </span><span class="kw">pub fn </span>new(name: ObjectName) -&gt; <span class="self">Self </span>{
<a href=#30 id=30 data-nosnippet>30</a> <span class="self">Self </span>{ name }
<a href=#31 id=31 data-nosnippet>31</a> }
<a href=#32 id=32 data-nosnippet>32</a>
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">pub fn </span>name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw-2">&amp;</span><span class="self">self</span>.name
<a href=#35 id=35 data-nosnippet>35</a> }
<a href=#36 id=36 data-nosnippet>36</a>}
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">impl </span>Display <span class="kw">for </span>DescribeTable {
<a href=#39 id=39 data-nosnippet>39</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#40 id=40 data-nosnippet>40</a> <span class="kw">let </span>name = <span class="self">self</span>.name();
<a href=#41 id=41 data-nosnippet>41</a> <span class="macro">write!</span>(f, <span class="string">r#"DESCRIBE TABLE {name}"#</span>)
<a href=#42 id=42 data-nosnippet>42</a> }
<a href=#43 id=43 data-nosnippet>43</a>}
<a href=#44 id=44 data-nosnippet>44</a>
<a href=#45 id=45 data-nosnippet>45</a><span class="attr">#[cfg(test)]
<a href=#46 id=46 data-nosnippet>46</a></span><span class="kw">mod </span>tests {
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">use </span>std::assert_matches;
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">use </span><span class="kw">crate</span>::util::format_raw_object_name;
<a href=#53 id=53 data-nosnippet>53</a>
<a href=#54 id=54 data-nosnippet>54</a> <span class="attr">#[test]
<a href=#55 id=55 data-nosnippet>55</a> </span><span class="kw">pub fn </span>test_describe_table() {
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">let </span>sql = <span class="string">"DESCRIBE TABLE test"</span>;
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#58 id=58 data-nosnippet>58</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#59 id=59 data-nosnippet>59</a> .unwrap();
<a href=#60 id=60 data-nosnippet>60</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#61 id=61 data-nosnippet>61</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DescribeTable { .. });
<a href=#62 id=62 data-nosnippet>62</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#63 id=63 data-nosnippet>63</a> Statement::DescribeTable(show) =&gt; {
<a href=#64 id=64 data-nosnippet>64</a> <span class="macro">assert_eq!</span>(format_raw_object_name(<span class="kw-2">&amp;</span>show.name), <span class="string">"test"</span>);
<a href=#65 id=65 data-nosnippet>65</a> }
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">_ </span>=&gt; {
<a href=#67 id=67 data-nosnippet>67</a> <span class="macro">unreachable!</span>();
<a href=#68 id=68 data-nosnippet>68</a> }
<a href=#69 id=69 data-nosnippet>69</a> }
<a href=#70 id=70 data-nosnippet>70</a> }
<a href=#71 id=71 data-nosnippet>71</a>
<a href=#72 id=72 data-nosnippet>72</a> <span class="attr">#[test]
<a href=#73 id=73 data-nosnippet>73</a> </span><span class="kw">pub fn </span>test_describe_schema_table() {
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">let </span>sql = <span class="string">"DESCRIBE TABLE test_schema.test"</span>;
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#76 id=76 data-nosnippet>76</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#77 id=77 data-nosnippet>77</a> .unwrap();
<a href=#78 id=78 data-nosnippet>78</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#79 id=79 data-nosnippet>79</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DescribeTable { .. });
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#81 id=81 data-nosnippet>81</a> Statement::DescribeTable(show) =&gt; {
<a href=#82 id=82 data-nosnippet>82</a> <span class="macro">assert_eq!</span>(format_raw_object_name(<span class="kw-2">&amp;</span>show.name), <span class="string">"test_schema.test"</span>);
<a href=#83 id=83 data-nosnippet>83</a> }
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw">_ </span>=&gt; {
<a href=#85 id=85 data-nosnippet>85</a> <span class="macro">unreachable!</span>();
<a href=#86 id=86 data-nosnippet>86</a> }
<a href=#87 id=87 data-nosnippet>87</a> }
<a href=#88 id=88 data-nosnippet>88</a> }
<a href=#89 id=89 data-nosnippet>89</a>
<a href=#90 id=90 data-nosnippet>90</a> <span class="attr">#[test]
<a href=#91 id=91 data-nosnippet>91</a> </span><span class="kw">pub fn </span>test_describe_catalog_schema_table() {
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">let </span>sql = <span class="string">"DESCRIBE TABLE test_catalog.test_schema.test"</span>;
<a href=#93 id=93 data-nosnippet>93</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#94 id=94 data-nosnippet>94</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#95 id=95 data-nosnippet>95</a> .unwrap();
<a href=#96 id=96 data-nosnippet>96</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#97 id=97 data-nosnippet>97</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DescribeTable { .. });
<a href=#98 id=98 data-nosnippet>98</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#99 id=99 data-nosnippet>99</a> Statement::DescribeTable(show) =&gt; {
<a href=#100 id=100 data-nosnippet>100</a> <span class="macro">assert_eq!</span>(
<a href=#101 id=101 data-nosnippet>101</a> format_raw_object_name(<span class="kw-2">&amp;</span>show.name),
<a href=#102 id=102 data-nosnippet>102</a> <span class="string">"test_catalog.test_schema.test"
<a href=#103 id=103 data-nosnippet>103</a> </span>);
<a href=#104 id=104 data-nosnippet>104</a> }
<a href=#105 id=105 data-nosnippet>105</a> <span class="kw">_ </span>=&gt; {
<a href=#106 id=106 data-nosnippet>106</a> <span class="macro">unreachable!</span>();
<a href=#107 id=107 data-nosnippet>107</a> }
<a href=#108 id=108 data-nosnippet>108</a> }
<a href=#109 id=109 data-nosnippet>109</a> }
<a href=#110 id=110 data-nosnippet>110</a>
<a href=#111 id=111 data-nosnippet>111</a> <span class="attr">#[test]
<a href=#112 id=112 data-nosnippet>112</a> </span><span class="kw">pub fn </span>test_describe_missing_table_name() {
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">let </span>sql = <span class="string">"DESCRIBE TABLE"</span>;
<a href=#114 id=114 data-nosnippet>114</a> <span class="macro">assert!</span>(
<a href=#115 id=115 data-nosnippet>115</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#116 id=116 data-nosnippet>116</a> .is_err()
<a href=#117 id=117 data-nosnippet>117</a> );
<a href=#118 id=118 data-nosnippet>118</a> }
<a href=#119 id=119 data-nosnippet>119</a>
<a href=#120 id=120 data-nosnippet>120</a> <span class="attr">#[test]
<a href=#121 id=121 data-nosnippet>121</a> </span><span class="kw">fn </span>test_display_describe_table() {
<a href=#122 id=122 data-nosnippet>122</a> <span class="kw">let </span>sql = <span class="string">r"describe table monitor;"</span>;
<a href=#123 id=123 data-nosnippet>123</a> <span class="kw">let </span>stmts =
<a href=#124 id=124 data-nosnippet>124</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#125 id=125 data-nosnippet>125</a> .unwrap();
<a href=#126 id=126 data-nosnippet>126</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#127 id=127 data-nosnippet>127</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DescribeTable { .. });
<a href=#128 id=128 data-nosnippet>128</a>
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#130 id=130 data-nosnippet>130</a> Statement::DescribeTable(set) =&gt; {
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#132 id=132 data-nosnippet>132</a> <span class="macro">assert_eq!</span>(
<a href=#133 id=133 data-nosnippet>133</a> <span class="string">r#"
<a href=#134 id=134 data-nosnippet>134</a>DESCRIBE TABLE monitor"#</span>,
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw-2">&amp;</span>new_sql
<a href=#136 id=136 data-nosnippet>136</a> );
<a href=#137 id=137 data-nosnippet>137</a> }
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">_ </span>=&gt; {
<a href=#139 id=139 data-nosnippet>139</a> <span class="macro">unreachable!</span>();
<a href=#140 id=140 data-nosnippet>140</a> }
<a href=#141 id=141 data-nosnippet>141</a> }
<a href=#142 id=142 data-nosnippet>142</a> }
<a href=#143 id=143 data-nosnippet>143</a>}
</code></pre></div></section></main></body></html>
+357
View File
@@ -0,0 +1,357 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/drop.rs`."><title>drop.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>drop.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#16 id=16 data-nosnippet>16</a></span><span class="kw">pub mod </span>trigger;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>std::fmt::Display;
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>serde::Serialize;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>sqlparser::ast::ObjectName;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="doccomment">/// DROP TABLE statement.
<a href=#25 id=25 data-nosnippet>25</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#26 id=26 data-nosnippet>26</a></span><span class="kw">pub struct </span>DropTable {
<a href=#27 id=27 data-nosnippet>27</a> table_names: Vec&lt;ObjectName&gt;,
<a href=#28 id=28 data-nosnippet>28</a>
<a href=#29 id=29 data-nosnippet>29</a> <span class="doccomment">/// drop table if exists
<a href=#30 id=30 data-nosnippet>30</a> </span>drop_if_exists: bool,
<a href=#31 id=31 data-nosnippet>31</a>}
<a href=#32 id=32 data-nosnippet>32</a>
<a href=#33 id=33 data-nosnippet>33</a><span class="kw">impl </span>DropTable {
<a href=#34 id=34 data-nosnippet>34</a> <span class="doccomment">/// Creates a statement for `DROP TABLE`
<a href=#35 id=35 data-nosnippet>35</a> </span><span class="kw">pub fn </span>new(table_names: Vec&lt;ObjectName&gt;, if_exists: bool) -&gt; <span class="self">Self </span>{
<a href=#36 id=36 data-nosnippet>36</a> <span class="self">Self </span>{
<a href=#37 id=37 data-nosnippet>37</a> table_names,
<a href=#38 id=38 data-nosnippet>38</a> drop_if_exists: if_exists,
<a href=#39 id=39 data-nosnippet>39</a> }
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a>
<a href=#42 id=42 data-nosnippet>42</a> <span class="kw">pub fn </span>table_names(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[ObjectName] {
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw-2">&amp;</span><span class="self">self</span>.table_names
<a href=#44 id=44 data-nosnippet>44</a> }
<a href=#45 id=45 data-nosnippet>45</a>
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">pub fn </span>drop_if_exists(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#47 id=47 data-nosnippet>47</a> <span class="self">self</span>.drop_if_exists
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a>}
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a><span class="kw">impl </span>Display <span class="kw">for </span>DropTable {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#53 id=53 data-nosnippet>53</a> f.write_str(<span class="string">"DROP TABLE"</span>)<span class="question-mark">?</span>;
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">if </span><span class="self">self</span>.drop_if_exists() {
<a href=#55 id=55 data-nosnippet>55</a> f.write_str(<span class="string">" IF EXISTS"</span>)<span class="question-mark">?</span>;
<a href=#56 id=56 data-nosnippet>56</a> }
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">let </span>table_names = <span class="self">self</span>.table_names();
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">for </span>(i, table_name) <span class="kw">in </span>table_names.iter().enumerate() {
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">if </span>i &gt; <span class="number">0 </span>{
<a href=#60 id=60 data-nosnippet>60</a> f.write_str(<span class="string">","</span>)<span class="question-mark">?</span>;
<a href=#61 id=61 data-nosnippet>61</a> }
<a href=#62 id=62 data-nosnippet>62</a> <span class="macro">write!</span>(f, <span class="string">" {}"</span>, table_name)<span class="question-mark">?</span>;
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a> <span class="prelude-val">Ok</span>(())
<a href=#65 id=65 data-nosnippet>65</a> }
<a href=#66 id=66 data-nosnippet>66</a>}
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a><span class="doccomment">/// `UNDROP TABLE` statement.
<a href=#69 id=69 data-nosnippet>69</a></span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#70 id=70 data-nosnippet>70</a>#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#71 id=71 data-nosnippet>71</a></span><span class="kw">pub struct </span>UndropTable {
<a href=#72 id=72 data-nosnippet>72</a> table_name: ObjectName,
<a href=#73 id=73 data-nosnippet>73</a>}
<a href=#74 id=74 data-nosnippet>74</a>
<a href=#75 id=75 data-nosnippet>75</a><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#76 id=76 data-nosnippet>76</a></span><span class="kw">impl </span>UndropTable {
<a href=#77 id=77 data-nosnippet>77</a> <span class="kw">pub fn </span>new(table_name: ObjectName) -&gt; <span class="self">Self </span>{
<a href=#78 id=78 data-nosnippet>78</a> <span class="self">Self </span>{ table_name }
<a href=#79 id=79 data-nosnippet>79</a> }
<a href=#80 id=80 data-nosnippet>80</a>
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">pub fn </span>table_name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw-2">&amp;</span><span class="self">self</span>.table_name
<a href=#83 id=83 data-nosnippet>83</a> }
<a href=#84 id=84 data-nosnippet>84</a>}
<a href=#85 id=85 data-nosnippet>85</a>
<a href=#86 id=86 data-nosnippet>86</a><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#87 id=87 data-nosnippet>87</a></span><span class="kw">impl </span>Display <span class="kw">for </span>UndropTable {
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#89 id=89 data-nosnippet>89</a> <span class="macro">write!</span>(f, <span class="string">"UNDROP TABLE {}"</span>, <span class="self">self</span>.table_name)
<a href=#90 id=90 data-nosnippet>90</a> }
<a href=#91 id=91 data-nosnippet>91</a>}
<a href=#92 id=92 data-nosnippet>92</a>
<a href=#93 id=93 data-nosnippet>93</a><span class="doccomment">/// DROP DATABASE statement.
<a href=#94 id=94 data-nosnippet>94</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#95 id=95 data-nosnippet>95</a></span><span class="kw">pub struct </span>DropDatabase {
<a href=#96 id=96 data-nosnippet>96</a> name: ObjectName,
<a href=#97 id=97 data-nosnippet>97</a> <span class="doccomment">/// drop table if exists
<a href=#98 id=98 data-nosnippet>98</a> </span>drop_if_exists: bool,
<a href=#99 id=99 data-nosnippet>99</a>}
<a href=#100 id=100 data-nosnippet>100</a>
<a href=#101 id=101 data-nosnippet>101</a><span class="kw">impl </span>DropDatabase {
<a href=#102 id=102 data-nosnippet>102</a> <span class="doccomment">/// Creates a statement for `DROP DATABASE`
<a href=#103 id=103 data-nosnippet>103</a> </span><span class="kw">pub fn </span>new(name: ObjectName, if_exists: bool) -&gt; <span class="self">Self </span>{
<a href=#104 id=104 data-nosnippet>104</a> <span class="self">Self </span>{
<a href=#105 id=105 data-nosnippet>105</a> name,
<a href=#106 id=106 data-nosnippet>106</a> drop_if_exists: if_exists,
<a href=#107 id=107 data-nosnippet>107</a> }
<a href=#108 id=108 data-nosnippet>108</a> }
<a href=#109 id=109 data-nosnippet>109</a>
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">pub fn </span>name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#111 id=111 data-nosnippet>111</a> <span class="kw-2">&amp;</span><span class="self">self</span>.name
<a href=#112 id=112 data-nosnippet>112</a> }
<a href=#113 id=113 data-nosnippet>113</a>
<a href=#114 id=114 data-nosnippet>114</a> <span class="kw">pub fn </span>drop_if_exists(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#115 id=115 data-nosnippet>115</a> <span class="self">self</span>.drop_if_exists
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a>}
<a href=#118 id=118 data-nosnippet>118</a>
<a href=#119 id=119 data-nosnippet>119</a><span class="kw">impl </span>Display <span class="kw">for </span>DropDatabase {
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#121 id=121 data-nosnippet>121</a> f.write_str(<span class="string">"DROP DATABASE"</span>)<span class="question-mark">?</span>;
<a href=#122 id=122 data-nosnippet>122</a> <span class="kw">if </span><span class="self">self</span>.drop_if_exists() {
<a href=#123 id=123 data-nosnippet>123</a> f.write_str(<span class="string">" IF EXISTS"</span>)<span class="question-mark">?</span>;
<a href=#124 id=124 data-nosnippet>124</a> }
<a href=#125 id=125 data-nosnippet>125</a> <span class="kw">let </span>name = <span class="self">self</span>.name();
<a href=#126 id=126 data-nosnippet>126</a> <span class="macro">write!</span>(f, <span class="string">r#" {name}"#</span>)
<a href=#127 id=127 data-nosnippet>127</a> }
<a href=#128 id=128 data-nosnippet>128</a>}
<a href=#129 id=129 data-nosnippet>129</a>
<a href=#130 id=130 data-nosnippet>130</a><span class="doccomment">/// DROP FLOW statement.
<a href=#131 id=131 data-nosnippet>131</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#132 id=132 data-nosnippet>132</a></span><span class="kw">pub struct </span>DropFlow {
<a href=#133 id=133 data-nosnippet>133</a> flow_name: ObjectName,
<a href=#134 id=134 data-nosnippet>134</a> <span class="doccomment">/// drop flow if exists
<a href=#135 id=135 data-nosnippet>135</a> </span>drop_if_exists: bool,
<a href=#136 id=136 data-nosnippet>136</a>}
<a href=#137 id=137 data-nosnippet>137</a>
<a href=#138 id=138 data-nosnippet>138</a><span class="kw">impl </span>DropFlow {
<a href=#139 id=139 data-nosnippet>139</a> <span class="doccomment">/// Creates a statement for `DROP DATABASE`
<a href=#140 id=140 data-nosnippet>140</a> </span><span class="kw">pub fn </span>new(flow_name: ObjectName, if_exists: bool) -&gt; <span class="self">Self </span>{
<a href=#141 id=141 data-nosnippet>141</a> <span class="self">Self </span>{
<a href=#142 id=142 data-nosnippet>142</a> flow_name,
<a href=#143 id=143 data-nosnippet>143</a> drop_if_exists: if_exists,
<a href=#144 id=144 data-nosnippet>144</a> }
<a href=#145 id=145 data-nosnippet>145</a> }
<a href=#146 id=146 data-nosnippet>146</a>
<a href=#147 id=147 data-nosnippet>147</a> <span class="doccomment">/// Returns the flow name.
<a href=#148 id=148 data-nosnippet>148</a> </span><span class="kw">pub fn </span>flow_name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw-2">&amp;</span><span class="self">self</span>.flow_name
<a href=#150 id=150 data-nosnippet>150</a> }
<a href=#151 id=151 data-nosnippet>151</a>
<a href=#152 id=152 data-nosnippet>152</a> <span class="doccomment">/// Return the `drop_if_exists`.
<a href=#153 id=153 data-nosnippet>153</a> </span><span class="kw">pub fn </span>drop_if_exists(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#154 id=154 data-nosnippet>154</a> <span class="self">self</span>.drop_if_exists
<a href=#155 id=155 data-nosnippet>155</a> }
<a href=#156 id=156 data-nosnippet>156</a>}
<a href=#157 id=157 data-nosnippet>157</a>
<a href=#158 id=158 data-nosnippet>158</a><span class="kw">impl </span>Display <span class="kw">for </span>DropFlow {
<a href=#159 id=159 data-nosnippet>159</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#160 id=160 data-nosnippet>160</a> f.write_str(<span class="string">"DROP FLOW"</span>)<span class="question-mark">?</span>;
<a href=#161 id=161 data-nosnippet>161</a> <span class="kw">if </span><span class="self">self</span>.drop_if_exists() {
<a href=#162 id=162 data-nosnippet>162</a> f.write_str(<span class="string">" IF EXISTS"</span>)<span class="question-mark">?</span>;
<a href=#163 id=163 data-nosnippet>163</a> }
<a href=#164 id=164 data-nosnippet>164</a> <span class="kw">let </span>flow_name = <span class="self">self</span>.flow_name();
<a href=#165 id=165 data-nosnippet>165</a> <span class="macro">write!</span>(f, <span class="string">r#" {flow_name}"#</span>)
<a href=#166 id=166 data-nosnippet>166</a> }
<a href=#167 id=167 data-nosnippet>167</a>}
<a href=#168 id=168 data-nosnippet>168</a>
<a href=#169 id=169 data-nosnippet>169</a><span class="doccomment">/// `DROP VIEW` statement.
<a href=#170 id=170 data-nosnippet>170</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#171 id=171 data-nosnippet>171</a></span><span class="kw">pub struct </span>DropView {
<a href=#172 id=172 data-nosnippet>172</a> <span class="comment">// The view name
<a href=#173 id=173 data-nosnippet>173</a> </span><span class="kw">pub </span>view_name: ObjectName,
<a href=#174 id=174 data-nosnippet>174</a> <span class="comment">// drop view if exists
<a href=#175 id=175 data-nosnippet>175</a> </span><span class="kw">pub </span>drop_if_exists: bool,
<a href=#176 id=176 data-nosnippet>176</a>}
<a href=#177 id=177 data-nosnippet>177</a>
<a href=#178 id=178 data-nosnippet>178</a><span class="kw">impl </span>Display <span class="kw">for </span>DropView {
<a href=#179 id=179 data-nosnippet>179</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#180 id=180 data-nosnippet>180</a> <span class="macro">write!</span>(
<a href=#181 id=181 data-nosnippet>181</a> f,
<a href=#182 id=182 data-nosnippet>182</a> <span class="string">"DROP VIEW{} {}"</span>,
<a href=#183 id=183 data-nosnippet>183</a> <span class="kw">if </span><span class="self">self</span>.drop_if_exists {
<a href=#184 id=184 data-nosnippet>184</a> <span class="string">" IF EXISTS"
<a href=#185 id=185 data-nosnippet>185</a> </span>} <span class="kw">else </span>{
<a href=#186 id=186 data-nosnippet>186</a> <span class="string">""
<a href=#187 id=187 data-nosnippet>187</a> </span>},
<a href=#188 id=188 data-nosnippet>188</a> <span class="self">self</span>.view_name
<a href=#189 id=189 data-nosnippet>189</a> )
<a href=#190 id=190 data-nosnippet>190</a> }
<a href=#191 id=191 data-nosnippet>191</a>}
<a href=#192 id=192 data-nosnippet>192</a>
<a href=#193 id=193 data-nosnippet>193</a><span class="attr">#[cfg(test)]
<a href=#194 id=194 data-nosnippet>194</a></span><span class="kw">mod </span>tests {
<a href=#195 id=195 data-nosnippet>195</a> <span class="kw">use </span>std::assert_matches;
<a href=#196 id=196 data-nosnippet>196</a>
<a href=#197 id=197 data-nosnippet>197</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#198 id=198 data-nosnippet>198</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#199 id=199 data-nosnippet>199</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#200 id=200 data-nosnippet>200</a>
<a href=#201 id=201 data-nosnippet>201</a> <span class="attr">#[test]
<a href=#202 id=202 data-nosnippet>202</a> </span><span class="kw">fn </span>test_display_drop_database() {
<a href=#203 id=203 data-nosnippet>203</a> <span class="kw">let </span>sql = <span class="string">r"drop database test;"</span>;
<a href=#204 id=204 data-nosnippet>204</a> <span class="kw">let </span>stmts =
<a href=#205 id=205 data-nosnippet>205</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#206 id=206 data-nosnippet>206</a> .unwrap();
<a href=#207 id=207 data-nosnippet>207</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#208 id=208 data-nosnippet>208</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropDatabase { .. });
<a href=#209 id=209 data-nosnippet>209</a>
<a href=#210 id=210 data-nosnippet>210</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#211 id=211 data-nosnippet>211</a> Statement::DropDatabase(set) =&gt; {
<a href=#212 id=212 data-nosnippet>212</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#213 id=213 data-nosnippet>213</a> <span class="macro">assert_eq!</span>(
<a href=#214 id=214 data-nosnippet>214</a> <span class="string">r#"
<a href=#215 id=215 data-nosnippet>215</a>DROP DATABASE test"#</span>,
<a href=#216 id=216 data-nosnippet>216</a> <span class="kw-2">&amp;</span>new_sql
<a href=#217 id=217 data-nosnippet>217</a> );
<a href=#218 id=218 data-nosnippet>218</a> }
<a href=#219 id=219 data-nosnippet>219</a> <span class="kw">_ </span>=&gt; {
<a href=#220 id=220 data-nosnippet>220</a> <span class="macro">unreachable!</span>();
<a href=#221 id=221 data-nosnippet>221</a> }
<a href=#222 id=222 data-nosnippet>222</a> }
<a href=#223 id=223 data-nosnippet>223</a>
<a href=#224 id=224 data-nosnippet>224</a> <span class="kw">let </span>sql = <span class="string">r"drop database if exists test;"</span>;
<a href=#225 id=225 data-nosnippet>225</a> <span class="kw">let </span>stmts =
<a href=#226 id=226 data-nosnippet>226</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#227 id=227 data-nosnippet>227</a> .unwrap();
<a href=#228 id=228 data-nosnippet>228</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#229 id=229 data-nosnippet>229</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropDatabase { .. });
<a href=#230 id=230 data-nosnippet>230</a>
<a href=#231 id=231 data-nosnippet>231</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#232 id=232 data-nosnippet>232</a> Statement::DropDatabase(set) =&gt; {
<a href=#233 id=233 data-nosnippet>233</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#234 id=234 data-nosnippet>234</a> <span class="macro">assert_eq!</span>(
<a href=#235 id=235 data-nosnippet>235</a> <span class="string">r#"
<a href=#236 id=236 data-nosnippet>236</a>DROP DATABASE IF EXISTS test"#</span>,
<a href=#237 id=237 data-nosnippet>237</a> <span class="kw-2">&amp;</span>new_sql
<a href=#238 id=238 data-nosnippet>238</a> );
<a href=#239 id=239 data-nosnippet>239</a> }
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">_ </span>=&gt; {
<a href=#241 id=241 data-nosnippet>241</a> <span class="macro">unreachable!</span>();
<a href=#242 id=242 data-nosnippet>242</a> }
<a href=#243 id=243 data-nosnippet>243</a> }
<a href=#244 id=244 data-nosnippet>244</a> }
<a href=#245 id=245 data-nosnippet>245</a>
<a href=#246 id=246 data-nosnippet>246</a> <span class="attr">#[test]
<a href=#247 id=247 data-nosnippet>247</a> </span><span class="kw">fn </span>test_display_drop_table() {
<a href=#248 id=248 data-nosnippet>248</a> <span class="kw">let </span>sql = <span class="string">r"drop table test;"</span>;
<a href=#249 id=249 data-nosnippet>249</a> <span class="kw">let </span>stmts =
<a href=#250 id=250 data-nosnippet>250</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#251 id=251 data-nosnippet>251</a> .unwrap();
<a href=#252 id=252 data-nosnippet>252</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#253 id=253 data-nosnippet>253</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropTable { .. });
<a href=#254 id=254 data-nosnippet>254</a>
<a href=#255 id=255 data-nosnippet>255</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#256 id=256 data-nosnippet>256</a> Statement::DropTable(set) =&gt; {
<a href=#257 id=257 data-nosnippet>257</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#258 id=258 data-nosnippet>258</a> <span class="macro">assert_eq!</span>(
<a href=#259 id=259 data-nosnippet>259</a> <span class="string">r#"
<a href=#260 id=260 data-nosnippet>260</a>DROP TABLE test"#</span>,
<a href=#261 id=261 data-nosnippet>261</a> <span class="kw-2">&amp;</span>new_sql
<a href=#262 id=262 data-nosnippet>262</a> );
<a href=#263 id=263 data-nosnippet>263</a> }
<a href=#264 id=264 data-nosnippet>264</a> <span class="kw">_ </span>=&gt; {
<a href=#265 id=265 data-nosnippet>265</a> <span class="macro">unreachable!</span>();
<a href=#266 id=266 data-nosnippet>266</a> }
<a href=#267 id=267 data-nosnippet>267</a> }
<a href=#268 id=268 data-nosnippet>268</a>
<a href=#269 id=269 data-nosnippet>269</a> <span class="kw">let </span>sql = <span class="string">r"drop table test1, test2;"</span>;
<a href=#270 id=270 data-nosnippet>270</a> <span class="kw">let </span>stmts =
<a href=#271 id=271 data-nosnippet>271</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#272 id=272 data-nosnippet>272</a> .unwrap();
<a href=#273 id=273 data-nosnippet>273</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#274 id=274 data-nosnippet>274</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropTable { .. });
<a href=#275 id=275 data-nosnippet>275</a>
<a href=#276 id=276 data-nosnippet>276</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#277 id=277 data-nosnippet>277</a> Statement::DropTable(set) =&gt; {
<a href=#278 id=278 data-nosnippet>278</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#279 id=279 data-nosnippet>279</a> <span class="macro">assert_eq!</span>(
<a href=#280 id=280 data-nosnippet>280</a> <span class="string">r#"
<a href=#281 id=281 data-nosnippet>281</a>DROP TABLE test1, test2"#</span>,
<a href=#282 id=282 data-nosnippet>282</a> <span class="kw-2">&amp;</span>new_sql
<a href=#283 id=283 data-nosnippet>283</a> );
<a href=#284 id=284 data-nosnippet>284</a> }
<a href=#285 id=285 data-nosnippet>285</a> <span class="kw">_ </span>=&gt; {
<a href=#286 id=286 data-nosnippet>286</a> <span class="macro">unreachable!</span>();
<a href=#287 id=287 data-nosnippet>287</a> }
<a href=#288 id=288 data-nosnippet>288</a> }
<a href=#289 id=289 data-nosnippet>289</a>
<a href=#290 id=290 data-nosnippet>290</a> <span class="kw">let </span>sql = <span class="string">r"drop table if exists test;"</span>;
<a href=#291 id=291 data-nosnippet>291</a> <span class="kw">let </span>stmts =
<a href=#292 id=292 data-nosnippet>292</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#293 id=293 data-nosnippet>293</a> .unwrap();
<a href=#294 id=294 data-nosnippet>294</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#295 id=295 data-nosnippet>295</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropTable { .. });
<a href=#296 id=296 data-nosnippet>296</a>
<a href=#297 id=297 data-nosnippet>297</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#298 id=298 data-nosnippet>298</a> Statement::DropTable(set) =&gt; {
<a href=#299 id=299 data-nosnippet>299</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#300 id=300 data-nosnippet>300</a> <span class="macro">assert_eq!</span>(
<a href=#301 id=301 data-nosnippet>301</a> <span class="string">r#"
<a href=#302 id=302 data-nosnippet>302</a>DROP TABLE IF EXISTS test"#</span>,
<a href=#303 id=303 data-nosnippet>303</a> <span class="kw-2">&amp;</span>new_sql
<a href=#304 id=304 data-nosnippet>304</a> );
<a href=#305 id=305 data-nosnippet>305</a> }
<a href=#306 id=306 data-nosnippet>306</a> <span class="kw">_ </span>=&gt; {
<a href=#307 id=307 data-nosnippet>307</a> <span class="macro">unreachable!</span>();
<a href=#308 id=308 data-nosnippet>308</a> }
<a href=#309 id=309 data-nosnippet>309</a> }
<a href=#310 id=310 data-nosnippet>310</a> }
<a href=#311 id=311 data-nosnippet>311</a>
<a href=#312 id=312 data-nosnippet>312</a> <span class="attr">#[test]
<a href=#313 id=313 data-nosnippet>313</a> </span><span class="kw">fn </span>test_display_drop_flow() {
<a href=#314 id=314 data-nosnippet>314</a> <span class="kw">let </span>sql = <span class="string">r"drop flow test;"</span>;
<a href=#315 id=315 data-nosnippet>315</a> <span class="kw">let </span>stmts =
<a href=#316 id=316 data-nosnippet>316</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#317 id=317 data-nosnippet>317</a> .unwrap();
<a href=#318 id=318 data-nosnippet>318</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#319 id=319 data-nosnippet>319</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropFlow { .. });
<a href=#320 id=320 data-nosnippet>320</a>
<a href=#321 id=321 data-nosnippet>321</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#322 id=322 data-nosnippet>322</a> Statement::DropFlow(set) =&gt; {
<a href=#323 id=323 data-nosnippet>323</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#324 id=324 data-nosnippet>324</a> <span class="macro">assert_eq!</span>(
<a href=#325 id=325 data-nosnippet>325</a> <span class="string">r#"
<a href=#326 id=326 data-nosnippet>326</a>DROP FLOW test"#</span>,
<a href=#327 id=327 data-nosnippet>327</a> <span class="kw-2">&amp;</span>new_sql
<a href=#328 id=328 data-nosnippet>328</a> );
<a href=#329 id=329 data-nosnippet>329</a> }
<a href=#330 id=330 data-nosnippet>330</a> <span class="kw">_ </span>=&gt; {
<a href=#331 id=331 data-nosnippet>331</a> <span class="macro">unreachable!</span>();
<a href=#332 id=332 data-nosnippet>332</a> }
<a href=#333 id=333 data-nosnippet>333</a> }
<a href=#334 id=334 data-nosnippet>334</a>
<a href=#335 id=335 data-nosnippet>335</a> <span class="kw">let </span>sql = <span class="string">r"drop flow if exists test;"</span>;
<a href=#336 id=336 data-nosnippet>336</a> <span class="kw">let </span>stmts =
<a href=#337 id=337 data-nosnippet>337</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#338 id=338 data-nosnippet>338</a> .unwrap();
<a href=#339 id=339 data-nosnippet>339</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#340 id=340 data-nosnippet>340</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::DropFlow { .. });
<a href=#341 id=341 data-nosnippet>341</a>
<a href=#342 id=342 data-nosnippet>342</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#343 id=343 data-nosnippet>343</a> Statement::DropFlow(set) =&gt; {
<a href=#344 id=344 data-nosnippet>344</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#345 id=345 data-nosnippet>345</a> <span class="macro">assert_eq!</span>(
<a href=#346 id=346 data-nosnippet>346</a> <span class="string">r#"
<a href=#347 id=347 data-nosnippet>347</a>DROP FLOW IF EXISTS test"#</span>,
<a href=#348 id=348 data-nosnippet>348</a> <span class="kw-2">&amp;</span>new_sql
<a href=#349 id=349 data-nosnippet>349</a> );
<a href=#350 id=350 data-nosnippet>350</a> }
<a href=#351 id=351 data-nosnippet>351</a> <span class="kw">_ </span>=&gt; {
<a href=#352 id=352 data-nosnippet>352</a> <span class="macro">unreachable!</span>();
<a href=#353 id=353 data-nosnippet>353</a> }
<a href=#354 id=354 data-nosnippet>354</a> }
<a href=#355 id=355 data-nosnippet>355</a> }
<a href=#356 id=356 data-nosnippet>356</a>}
</code></pre></div></section></main></body></html>
+59
View File
@@ -0,0 +1,59 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/explain.rs`."><title>explain.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>explain.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::{Display, Formatter};
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::AnalyzeFormat;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="doccomment">/// Explain statement.
<a href=#24 id=24 data-nosnippet>24</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#25 id=25 data-nosnippet>25</a></span><span class="kw">pub struct </span>ExplainStatement {
<a href=#26 id=26 data-nosnippet>26</a> <span class="doccomment">/// `EXPLAIN ANALYZE ..`
<a href=#27 id=27 data-nosnippet>27</a> </span><span class="kw">pub </span>analyze: bool,
<a href=#28 id=28 data-nosnippet>28</a> <span class="doccomment">/// `EXPLAIN .. VERBOSE ..`
<a href=#29 id=29 data-nosnippet>29</a> </span><span class="kw">pub </span>verbose: bool,
<a href=#30 id=30 data-nosnippet>30</a> <span class="doccomment">/// `EXPLAIN .. FORMAT `
<a href=#31 id=31 data-nosnippet>31</a> </span><span class="kw">pub </span>format: <span class="prelude-ty">Option</span>&lt;AnalyzeFormat&gt;,
<a href=#32 id=32 data-nosnippet>32</a> <span class="doccomment">/// The statement to analyze. Note this is a Greptime [`Statement`] (not a
<a href=#33 id=33 data-nosnippet>33</a> /// [`sqlparser::ast::Statement`] so that we can use
<a href=#34 id=34 data-nosnippet>34</a> /// Greptime specific statements
<a href=#35 id=35 data-nosnippet>35</a> </span><span class="kw">pub </span>statement: Box&lt;Statement&gt;,
<a href=#36 id=36 data-nosnippet>36</a>}
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">impl </span>ExplainStatement {
<a href=#39 id=39 data-nosnippet>39</a> <span class="kw">pub fn </span>format(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;AnalyzeFormat&gt; {
<a href=#40 id=40 data-nosnippet>40</a> <span class="self">self</span>.format
<a href=#41 id=41 data-nosnippet>41</a> }
<a href=#42 id=42 data-nosnippet>42</a>}
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a><span class="kw">impl </span>Display <span class="kw">for </span>ExplainStatement {
<a href=#45 id=45 data-nosnippet>45</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#46 id=46 data-nosnippet>46</a> <span class="macro">write!</span>(f, <span class="string">"EXPLAIN"</span>)<span class="question-mark">?</span>;
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">if </span><span class="self">self</span>.analyze {
<a href=#48 id=48 data-nosnippet>48</a> <span class="macro">write!</span>(f, <span class="string">" ANALYZE"</span>)<span class="question-mark">?</span>;
<a href=#49 id=49 data-nosnippet>49</a> }
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">if </span><span class="self">self</span>.verbose {
<a href=#51 id=51 data-nosnippet>51</a> <span class="macro">write!</span>(f, <span class="string">" VERBOSE"</span>)<span class="question-mark">?</span>;
<a href=#52 id=52 data-nosnippet>52</a> }
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(format) = <span class="kw-2">&amp;</span><span class="self">self</span>.format {
<a href=#54 id=54 data-nosnippet>54</a> <span class="macro">write!</span>(f, <span class="string">" FORMAT {}"</span>, format)<span class="question-mark">?</span>;
<a href=#55 id=55 data-nosnippet>55</a> }
<a href=#56 id=56 data-nosnippet>56</a> <span class="macro">write!</span>(f, <span class="string">" {}"</span>, <span class="self">self</span>.statement)
<a href=#57 id=57 data-nosnippet>57</a> }
<a href=#58 id=58 data-nosnippet>58</a>}
</code></pre></div></section></main></body></html>
+434
View File
@@ -0,0 +1,434 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/insert.rs`."><title>insert.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>insert.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>serde::Serialize;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>sqlparser::ast::{
<a href=#17 id=17 data-nosnippet>17</a> Insert <span class="kw">as </span>SpInsert, ObjectName, ObjectNamePart, Parens, SetExpr, Statement, TableObject,
<a href=#18 id=18 data-nosnippet>18</a> UnaryOperator, ValueWithSpan, Values,
<a href=#19 id=19 data-nosnippet>19</a>};
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>sqlparser::parser::ParserError;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::ast::{Expr, Value};
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span><span class="kw">crate</span>::error::{<span class="prelude-ty">Result</span>, UnsupportedSnafu};
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::statements::query::Query <span class="kw">as </span>GtQuery;
<a href=#26 id=26 data-nosnippet>26</a>
<a href=#27 id=27 data-nosnippet>27</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#28 id=28 data-nosnippet>28</a></span><span class="kw">pub struct </span>Insert {
<a href=#29 id=29 data-nosnippet>29</a> <span class="comment">// Can only be sqlparser::ast::Statement::Insert variant
<a href=#30 id=30 data-nosnippet>30</a> </span><span class="kw">pub </span>inner: Statement,
<a href=#31 id=31 data-nosnippet>31</a>}
<a href=#32 id=32 data-nosnippet>32</a>
<a href=#33 id=33 data-nosnippet>33</a><span class="macro">macro_rules!</span> parse_fail {
<a href=#34 id=34 data-nosnippet>34</a> (<span class="macro-nonterminal">$expr</span>: expr) =&gt; {
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">return </span><span class="kw">crate</span>::error::ParseSqlValueSnafu {
<a href=#36 id=36 data-nosnippet>36</a> msg: <span class="macro">format!</span>(<span class="string">"{:?}"</span>, <span class="macro-nonterminal">$expr</span>),
<a href=#37 id=37 data-nosnippet>37</a> }
<a href=#38 id=38 data-nosnippet>38</a> .fail();
<a href=#39 id=39 data-nosnippet>39</a> };
<a href=#40 id=40 data-nosnippet>40</a>}
<a href=#41 id=41 data-nosnippet>41</a>
<a href=#42 id=42 data-nosnippet>42</a><span class="kw">impl </span>Insert {
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw">pub fn </span>table_name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="kw-2">&amp;</span>ObjectName&gt; {
<a href=#44 id=44 data-nosnippet>44</a> <span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.inner {
<a href=#45 id=45 data-nosnippet>45</a> Statement::Insert(insert) =&gt; {
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">let </span>TableObject::TableName(name) = <span class="kw-2">&amp;</span>insert.table <span class="kw">else </span>{
<a href=#47 id=47 data-nosnippet>47</a> <span class="kw">return </span>UnsupportedSnafu {
<a href=#48 id=48 data-nosnippet>48</a> keyword: <span class="string">"TABLE FUNCTION"</span>.to_string(),
<a href=#49 id=49 data-nosnippet>49</a> }
<a href=#50 id=50 data-nosnippet>50</a> .fail();
<a href=#51 id=51 data-nosnippet>51</a> };
<a href=#52 id=52 data-nosnippet>52</a> <span class="prelude-val">Ok</span>(name)
<a href=#53 id=53 data-nosnippet>53</a> }
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#55 id=55 data-nosnippet>55</a> }
<a href=#56 id=56 data-nosnippet>56</a> }
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">pub fn </span>columns(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;<span class="kw-2">&amp;</span>String&gt; {
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.inner {
<a href=#60 id=60 data-nosnippet>60</a> Statement::Insert(insert) =&gt; insert
<a href=#61 id=61 data-nosnippet>61</a> .columns
<a href=#62 id=62 data-nosnippet>62</a> .iter()
<a href=#63 id=63 data-nosnippet>63</a> .filter_map(single_part_column_ident)
<a href=#64 id=64 data-nosnippet>64</a> .map(|ident| <span class="kw-2">&amp;</span>ident.value)
<a href=#65 id=65 data-nosnippet>65</a> .collect(),
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#67 id=67 data-nosnippet>67</a> }
<a href=#68 id=68 data-nosnippet>68</a> }
<a href=#69 id=69 data-nosnippet>69</a>
<a href=#70 id=70 data-nosnippet>70</a> <span class="doccomment">/// Extracts the literal insert statement body if possible
<a href=#71 id=71 data-nosnippet>71</a> </span><span class="kw">pub fn </span>values_body(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;Vec&lt;Value&gt;&gt;&gt; {
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.inner {
<a href=#73 id=73 data-nosnippet>73</a> Statement::Insert(SpInsert { source, .. }) =&gt; {
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">let </span>rows = source
<a href=#75 id=75 data-nosnippet>75</a> .as_deref()
<a href=#76 id=76 data-nosnippet>76</a> .and_then(|query| <span class="kw">match </span>query.body.as_ref() {
<a href=#77 id=77 data-nosnippet>77</a> SetExpr::Values(Values { rows, .. }) =&gt; <span class="prelude-val">Some</span>(rows),
<a href=#78 id=78 data-nosnippet>78</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#79 id=79 data-nosnippet>79</a> });
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">match </span>rows {
<a href=#81 id=81 data-nosnippet>81</a> <span class="prelude-val">Some</span>(rows) =&gt; sql_exprs_to_values(rows),
<a href=#82 id=82 data-nosnippet>82</a> <span class="prelude-val">None </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#83 id=83 data-nosnippet>83</a> }
<a href=#84 id=84 data-nosnippet>84</a> }
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#86 id=86 data-nosnippet>86</a> }
<a href=#87 id=87 data-nosnippet>87</a> }
<a href=#88 id=88 data-nosnippet>88</a>
<a href=#89 id=89 data-nosnippet>89</a> <span class="doccomment">/// Returns true when the insert statement can extract literal values.
<a href=#90 id=90 data-nosnippet>90</a> /// The rules is the same as function `values_body()`.
<a href=#91 id=91 data-nosnippet>91</a> </span><span class="kw">pub fn </span>can_extract_values(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.inner {
<a href=#93 id=93 data-nosnippet>93</a> Statement::Insert(SpInsert { source, .. }) =&gt; source
<a href=#94 id=94 data-nosnippet>94</a> .as_deref()
<a href=#95 id=95 data-nosnippet>95</a> .and_then(|query| <span class="kw">match </span>query.body.as_ref() {
<a href=#96 id=96 data-nosnippet>96</a> SetExpr::Values(Values { rows, .. }) =&gt; <span class="prelude-val">Some</span>(rows),
<a href=#97 id=97 data-nosnippet>97</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#98 id=98 data-nosnippet>98</a> })
<a href=#99 id=99 data-nosnippet>99</a> .is_some_and(|rows| {
<a href=#100 id=100 data-nosnippet>100</a> rows.iter().all(|es| {
<a href=#101 id=101 data-nosnippet>101</a> es.iter().all(|expr| <span class="kw">match </span>expr {
<a href=#102 id=102 data-nosnippet>102</a> Expr::Value(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<a href=#103 id=103 data-nosnippet>103</a> Expr::Identifier(ident) =&gt; {
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">if </span>ident.quote_style.is_none() {
<a href=#105 id=105 data-nosnippet>105</a> ident.value.to_lowercase() == <span class="string">"default"
<a href=#106 id=106 data-nosnippet>106</a> </span>} <span class="kw">else </span>{
<a href=#107 id=107 data-nosnippet>107</a> ident.quote_style == <span class="prelude-val">Some</span>(<span class="string">'"'</span>)
<a href=#108 id=108 data-nosnippet>108</a> }
<a href=#109 id=109 data-nosnippet>109</a> }
<a href=#110 id=110 data-nosnippet>110</a> Expr::UnaryOp { op, expr } =&gt; {
<a href=#111 id=111 data-nosnippet>111</a> <span class="macro">matches!</span>(op, UnaryOperator::Minus | UnaryOperator::Plus)
<a href=#112 id=112 data-nosnippet>112</a> &amp;&amp; <span class="macro">matches!</span>(
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw-2">&amp;**</span>expr,
<a href=#114 id=114 data-nosnippet>114</a> Expr::Value(ValueWithSpan {
<a href=#115 id=115 data-nosnippet>115</a> value: Value::Number(<span class="kw">_</span>, <span class="kw">_</span>),
<a href=#116 id=116 data-nosnippet>116</a> ..
<a href=#117 id=117 data-nosnippet>117</a> })
<a href=#118 id=118 data-nosnippet>118</a> )
<a href=#119 id=119 data-nosnippet>119</a> }
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">_ </span>=&gt; <span class="bool-val">false</span>,
<a href=#121 id=121 data-nosnippet>121</a> })
<a href=#122 id=122 data-nosnippet>122</a> })
<a href=#123 id=123 data-nosnippet>123</a> }),
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">_ </span>=&gt; <span class="bool-val">false</span>,
<a href=#125 id=125 data-nosnippet>125</a> }
<a href=#126 id=126 data-nosnippet>126</a> }
<a href=#127 id=127 data-nosnippet>127</a>
<a href=#128 id=128 data-nosnippet>128</a> <span class="doccomment">/// Returns true when the insert source is a query rather than `VALUES`.
<a href=#129 id=129 data-nosnippet>129</a> </span><span class="kw">pub fn </span>has_non_values_query_source(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.inner {
<a href=#131 id=131 data-nosnippet>131</a> Statement::Insert(SpInsert {
<a href=#132 id=132 data-nosnippet>132</a> source: <span class="prelude-val">Some</span>(query),
<a href=#133 id=133 data-nosnippet>133</a> ..
<a href=#134 id=134 data-nosnippet>134</a> }) =&gt; !<span class="macro">matches!</span>(<span class="kw-2">&amp;*</span>query.body, SetExpr::Values(<span class="kw">_</span>)),
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">_ </span>=&gt; <span class="bool-val">false</span>,
<a href=#136 id=136 data-nosnippet>136</a> }
<a href=#137 id=137 data-nosnippet>137</a> }
<a href=#138 id=138 data-nosnippet>138</a>
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw">pub fn </span>query_body(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="prelude-ty">Option</span>&lt;GtQuery&gt;&gt; {
<a href=#140 id=140 data-nosnippet>140</a> <span class="prelude-val">Ok</span>(<span class="kw">match </span><span class="kw-2">&amp;</span><span class="self">self</span>.inner {
<a href=#141 id=141 data-nosnippet>141</a> Statement::Insert(SpInsert {
<a href=#142 id=142 data-nosnippet>142</a> source: <span class="prelude-val">Some</span>(query),
<a href=#143 id=143 data-nosnippet>143</a> ..
<a href=#144 id=144 data-nosnippet>144</a> }) =&gt; <span class="prelude-val">Some</span>(query.as_ref().clone().try_into()<span class="question-mark">?</span>),
<a href=#145 id=145 data-nosnippet>145</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#146 id=146 data-nosnippet>146</a> })
<a href=#147 id=147 data-nosnippet>147</a> }
<a href=#148 id=148 data-nosnippet>148</a>}
<a href=#149 id=149 data-nosnippet>149</a>
<a href=#150 id=150 data-nosnippet>150</a><span class="kw">fn </span>sql_exprs_to_values(exprs: <span class="kw-2">&amp;</span>[Parens&lt;Vec&lt;Expr&gt;&gt;]) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;Vec&lt;Value&gt;&gt;&gt; {
<a href=#151 id=151 data-nosnippet>151</a> <span class="kw">let </span><span class="kw-2">mut </span>values = Vec::with_capacity(exprs.len());
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">for </span>es <span class="kw">in </span>exprs.iter() {
<a href=#153 id=153 data-nosnippet>153</a> <span class="kw">let </span><span class="kw-2">mut </span>vs = Vec::with_capacity(es.len());
<a href=#154 id=154 data-nosnippet>154</a> <span class="kw">for </span>expr <span class="kw">in </span>es.iter() {
<a href=#155 id=155 data-nosnippet>155</a> vs.push(<span class="kw">match </span>expr {
<a href=#156 id=156 data-nosnippet>156</a> Expr::Value(v) =&gt; v.value.clone(),
<a href=#157 id=157 data-nosnippet>157</a> Expr::Identifier(ident) =&gt; {
<a href=#158 id=158 data-nosnippet>158</a> <span class="kw">if </span>ident.quote_style.is_none() {
<a href=#159 id=159 data-nosnippet>159</a> <span class="comment">// Special processing for `default` value
<a href=#160 id=160 data-nosnippet>160</a> </span><span class="kw">if </span>ident.value.to_lowercase() == <span class="string">"default" </span>{
<a href=#161 id=161 data-nosnippet>161</a> Value::Placeholder(ident.value.clone())
<a href=#162 id=162 data-nosnippet>162</a> } <span class="kw">else </span>{
<a href=#163 id=163 data-nosnippet>163</a> <span class="macro">parse_fail!</span>(expr);
<a href=#164 id=164 data-nosnippet>164</a> }
<a href=#165 id=165 data-nosnippet>165</a> } <span class="kw">else </span>{
<a href=#166 id=166 data-nosnippet>166</a> <span class="comment">// Identifiers with double quotes, we treat them as strings.
<a href=#167 id=167 data-nosnippet>167</a> </span><span class="kw">if </span>ident.quote_style == <span class="prelude-val">Some</span>(<span class="string">'"'</span>) {
<a href=#168 id=168 data-nosnippet>168</a> Value::SingleQuotedString(ident.value.clone())
<a href=#169 id=169 data-nosnippet>169</a> } <span class="kw">else </span>{
<a href=#170 id=170 data-nosnippet>170</a> <span class="macro">parse_fail!</span>(expr);
<a href=#171 id=171 data-nosnippet>171</a> }
<a href=#172 id=172 data-nosnippet>172</a> }
<a href=#173 id=173 data-nosnippet>173</a> }
<a href=#174 id=174 data-nosnippet>174</a> Expr::UnaryOp { op, expr }
<a href=#175 id=175 data-nosnippet>175</a> <span class="kw">if </span><span class="macro">matches!</span>(op, UnaryOperator::Minus | UnaryOperator::Plus) =&gt;
<a href=#176 id=176 data-nosnippet>176</a> {
<a href=#177 id=177 data-nosnippet>177</a> <span class="kw">if let </span>Expr::Value(ValueWithSpan {
<a href=#178 id=178 data-nosnippet>178</a> value: Value::Number(s, b),
<a href=#179 id=179 data-nosnippet>179</a> ..
<a href=#180 id=180 data-nosnippet>180</a> }) = <span class="kw-2">&amp;**</span>expr
<a href=#181 id=181 data-nosnippet>181</a> {
<a href=#182 id=182 data-nosnippet>182</a> <span class="kw">match </span>op {
<a href=#183 id=183 data-nosnippet>183</a> UnaryOperator::Minus =&gt; Value::Number(<span class="macro">format!</span>(<span class="string">"-{s}"</span>), <span class="kw-2">*</span>b),
<a href=#184 id=184 data-nosnippet>184</a> UnaryOperator::Plus =&gt; Value::Number(s.clone(), <span class="kw-2">*</span>b),
<a href=#185 id=185 data-nosnippet>185</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#186 id=186 data-nosnippet>186</a> }
<a href=#187 id=187 data-nosnippet>187</a> } <span class="kw">else </span>{
<a href=#188 id=188 data-nosnippet>188</a> <span class="macro">parse_fail!</span>(expr);
<a href=#189 id=189 data-nosnippet>189</a> }
<a href=#190 id=190 data-nosnippet>190</a> }
<a href=#191 id=191 data-nosnippet>191</a> <span class="kw">_ </span>=&gt; {
<a href=#192 id=192 data-nosnippet>192</a> <span class="macro">parse_fail!</span>(expr);
<a href=#193 id=193 data-nosnippet>193</a> }
<a href=#194 id=194 data-nosnippet>194</a> });
<a href=#195 id=195 data-nosnippet>195</a> }
<a href=#196 id=196 data-nosnippet>196</a> values.push(vs);
<a href=#197 id=197 data-nosnippet>197</a> }
<a href=#198 id=198 data-nosnippet>198</a> <span class="prelude-val">Ok</span>(values)
<a href=#199 id=199 data-nosnippet>199</a>}
<a href=#200 id=200 data-nosnippet>200</a>
<a href=#201 id=201 data-nosnippet>201</a><span class="kw">fn </span>single_part_column_ident(name: <span class="kw-2">&amp;</span>ObjectName) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>sqlparser::ast::Ident&gt; {
<a href=#202 id=202 data-nosnippet>202</a> <span class="kw">let </span>[ObjectNamePart::Identifier(ident)] = name.<span class="number">0</span>.as_slice() <span class="kw">else </span>{
<a href=#203 id=203 data-nosnippet>203</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#204 id=204 data-nosnippet>204</a> };
<a href=#205 id=205 data-nosnippet>205</a> <span class="prelude-val">Some</span>(ident)
<a href=#206 id=206 data-nosnippet>206</a>}
<a href=#207 id=207 data-nosnippet>207</a>
<a href=#208 id=208 data-nosnippet>208</a><span class="kw">impl </span>TryFrom&lt;Statement&gt; <span class="kw">for </span>Insert {
<a href=#209 id=209 data-nosnippet>209</a> <span class="kw">type </span>Error = ParserError;
<a href=#210 id=210 data-nosnippet>210</a>
<a href=#211 id=211 data-nosnippet>211</a> <span class="kw">fn </span>try_from(value: Statement) -&gt; std::result::Result&lt;<span class="self">Self</span>, <span class="self">Self</span>::Error&gt; {
<a href=#212 id=212 data-nosnippet>212</a> <span class="kw">let </span>Statement::Insert(insert) = <span class="kw-2">&amp;</span>value <span class="kw">else </span>{
<a href=#213 id=213 data-nosnippet>213</a> <span class="kw">return </span><span class="prelude-val">Err</span>(ParserError::ParserError(<span class="macro">format!</span>(
<a href=#214 id=214 data-nosnippet>214</a> <span class="string">"Not expected to be {value}"
<a href=#215 id=215 data-nosnippet>215</a> </span>)));
<a href=#216 id=216 data-nosnippet>216</a> };
<a href=#217 id=217 data-nosnippet>217</a>
<a href=#218 id=218 data-nosnippet>218</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(column) = insert
<a href=#219 id=219 data-nosnippet>219</a> .columns
<a href=#220 id=220 data-nosnippet>220</a> .iter()
<a href=#221 id=221 data-nosnippet>221</a> .find(|column| single_part_column_ident(column).is_none())
<a href=#222 id=222 data-nosnippet>222</a> {
<a href=#223 id=223 data-nosnippet>223</a> <span class="kw">return </span><span class="prelude-val">Err</span>(ParserError::ParserError(<span class="macro">format!</span>(
<a href=#224 id=224 data-nosnippet>224</a> <span class="string">"Expected a single-part insert column name, found {column}"
<a href=#225 id=225 data-nosnippet>225</a> </span>)));
<a href=#226 id=226 data-nosnippet>226</a> }
<a href=#227 id=227 data-nosnippet>227</a>
<a href=#228 id=228 data-nosnippet>228</a> <span class="prelude-val">Ok</span>(Insert { inner: value })
<a href=#229 id=229 data-nosnippet>229</a> }
<a href=#230 id=230 data-nosnippet>230</a>}
<a href=#231 id=231 data-nosnippet>231</a>
<a href=#232 id=232 data-nosnippet>232</a><span class="attr">#[cfg(test)]
<a href=#233 id=233 data-nosnippet>233</a></span><span class="kw">mod </span>tests {
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#235 id=235 data-nosnippet>235</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#236 id=236 data-nosnippet>236</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#237 id=237 data-nosnippet>237</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#238 id=238 data-nosnippet>238</a>
<a href=#239 id=239 data-nosnippet>239</a> <span class="attr">#[test]
<a href=#240 id=240 data-nosnippet>240</a> </span><span class="kw">fn </span>test_insert_value_with_unary_op() {
<a href=#241 id=241 data-nosnippet>241</a> <span class="comment">// insert "-1"
<a href=#242 id=242 data-nosnippet>242</a> </span><span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES(-1)"</span>;
<a href=#243 id=243 data-nosnippet>243</a> <span class="kw">let </span>stmt =
<a href=#244 id=244 data-nosnippet>244</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#245 id=245 data-nosnippet>245</a> .unwrap()
<a href=#246 id=246 data-nosnippet>246</a> .remove(<span class="number">0</span>);
<a href=#247 id=247 data-nosnippet>247</a> <span class="kw">match </span>stmt {
<a href=#248 id=248 data-nosnippet>248</a> Statement::Insert(insert) =&gt; {
<a href=#249 id=249 data-nosnippet>249</a> <span class="kw">let </span>values = insert.values_body().unwrap();
<a href=#250 id=250 data-nosnippet>250</a> <span class="macro">assert_eq!</span>(values, <span class="macro">vec!</span>[<span class="macro">vec!</span>[Value::Number(<span class="string">"-1"</span>.to_string(), <span class="bool-val">false</span>)]]);
<a href=#251 id=251 data-nosnippet>251</a> }
<a href=#252 id=252 data-nosnippet>252</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#253 id=253 data-nosnippet>253</a> }
<a href=#254 id=254 data-nosnippet>254</a>
<a href=#255 id=255 data-nosnippet>255</a> <span class="comment">// insert "+1"
<a href=#256 id=256 data-nosnippet>256</a> </span><span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES(+1)"</span>;
<a href=#257 id=257 data-nosnippet>257</a> <span class="kw">let </span>stmt =
<a href=#258 id=258 data-nosnippet>258</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#259 id=259 data-nosnippet>259</a> .unwrap()
<a href=#260 id=260 data-nosnippet>260</a> .remove(<span class="number">0</span>);
<a href=#261 id=261 data-nosnippet>261</a> <span class="kw">match </span>stmt {
<a href=#262 id=262 data-nosnippet>262</a> Statement::Insert(insert) =&gt; {
<a href=#263 id=263 data-nosnippet>263</a> <span class="kw">let </span>values = insert.values_body().unwrap();
<a href=#264 id=264 data-nosnippet>264</a> <span class="macro">assert_eq!</span>(values, <span class="macro">vec!</span>[<span class="macro">vec!</span>[Value::Number(<span class="string">"1"</span>.to_string(), <span class="bool-val">false</span>)]]);
<a href=#265 id=265 data-nosnippet>265</a> }
<a href=#266 id=266 data-nosnippet>266</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#267 id=267 data-nosnippet>267</a> }
<a href=#268 id=268 data-nosnippet>268</a> }
<a href=#269 id=269 data-nosnippet>269</a>
<a href=#270 id=270 data-nosnippet>270</a> <span class="attr">#[test]
<a href=#271 id=271 data-nosnippet>271</a> </span><span class="kw">fn </span>test_insert_column_names_are_single_identifiers() {
<a href=#272 id=272 data-nosnippet>272</a> <span class="kw">let </span>stmt = ParserContext::create_with_dialect(
<a href=#273 id=273 data-nosnippet>273</a> <span class="string">"INSERT INTO my_table (host, \"value\") VALUES (1, 2)"</span>,
<a href=#274 id=274 data-nosnippet>274</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#275 id=275 data-nosnippet>275</a> ParseOptions::default(),
<a href=#276 id=276 data-nosnippet>276</a> )
<a href=#277 id=277 data-nosnippet>277</a> .unwrap()
<a href=#278 id=278 data-nosnippet>278</a> .remove(<span class="number">0</span>);
<a href=#279 id=279 data-nosnippet>279</a> <span class="kw">let </span>Statement::Insert(insert) = stmt <span class="kw">else </span>{
<a href=#280 id=280 data-nosnippet>280</a> <span class="macro">unreachable!</span>()
<a href=#281 id=281 data-nosnippet>281</a> };
<a href=#282 id=282 data-nosnippet>282</a> <span class="macro">assert_eq!</span>(insert.columns(), <span class="macro">vec!</span>[<span class="string">"host"</span>, <span class="string">"value"</span>]);
<a href=#283 id=283 data-nosnippet>283</a>
<a href=#284 id=284 data-nosnippet>284</a> <span class="kw">let </span>result = ParserContext::create_with_dialect(
<a href=#285 id=285 data-nosnippet>285</a> <span class="string">"INSERT INTO my_table (metric.host) VALUES (1)"</span>,
<a href=#286 id=286 data-nosnippet>286</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#287 id=287 data-nosnippet>287</a> ParseOptions::default(),
<a href=#288 id=288 data-nosnippet>288</a> );
<a href=#289 id=289 data-nosnippet>289</a> <span class="kw">let </span>error = result.unwrap_err().to_string();
<a href=#290 id=290 data-nosnippet>290</a> <span class="macro">assert!</span>(
<a href=#291 id=291 data-nosnippet>291</a> error.contains(<span class="string">"Expected a single-part insert column name, found metric.host"</span>),
<a href=#292 id=292 data-nosnippet>292</a> <span class="string">"unexpected error: {error}"
<a href=#293 id=293 data-nosnippet>293</a> </span>);
<a href=#294 id=294 data-nosnippet>294</a> }
<a href=#295 id=295 data-nosnippet>295</a>
<a href=#296 id=296 data-nosnippet>296</a> <span class="attr">#[test]
<a href=#297 id=297 data-nosnippet>297</a> </span><span class="kw">fn </span>test_insert_value_with_default() {
<a href=#298 id=298 data-nosnippet>298</a> <span class="comment">// insert "default"
<a href=#299 id=299 data-nosnippet>299</a> </span><span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES(default)"</span>;
<a href=#300 id=300 data-nosnippet>300</a> <span class="kw">let </span>stmt =
<a href=#301 id=301 data-nosnippet>301</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#302 id=302 data-nosnippet>302</a> .unwrap()
<a href=#303 id=303 data-nosnippet>303</a> .remove(<span class="number">0</span>);
<a href=#304 id=304 data-nosnippet>304</a> <span class="kw">match </span>stmt {
<a href=#305 id=305 data-nosnippet>305</a> Statement::Insert(insert) =&gt; {
<a href=#306 id=306 data-nosnippet>306</a> <span class="kw">let </span>values = insert.values_body().unwrap();
<a href=#307 id=307 data-nosnippet>307</a> <span class="macro">assert_eq!</span>(values, <span class="macro">vec!</span>[<span class="macro">vec!</span>[Value::Placeholder(<span class="string">"default"</span>.to_owned())]]);
<a href=#308 id=308 data-nosnippet>308</a> }
<a href=#309 id=309 data-nosnippet>309</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#310 id=310 data-nosnippet>310</a> }
<a href=#311 id=311 data-nosnippet>311</a> }
<a href=#312 id=312 data-nosnippet>312</a>
<a href=#313 id=313 data-nosnippet>313</a> <span class="attr">#[test]
<a href=#314 id=314 data-nosnippet>314</a> </span><span class="kw">fn </span>test_insert_value_with_default_uppercase() {
<a href=#315 id=315 data-nosnippet>315</a> <span class="comment">// insert "DEFAULT"
<a href=#316 id=316 data-nosnippet>316</a> </span><span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES(DEFAULT)"</span>;
<a href=#317 id=317 data-nosnippet>317</a> <span class="kw">let </span>stmt =
<a href=#318 id=318 data-nosnippet>318</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#319 id=319 data-nosnippet>319</a> .unwrap()
<a href=#320 id=320 data-nosnippet>320</a> .remove(<span class="number">0</span>);
<a href=#321 id=321 data-nosnippet>321</a> <span class="kw">match </span>stmt {
<a href=#322 id=322 data-nosnippet>322</a> Statement::Insert(insert) =&gt; {
<a href=#323 id=323 data-nosnippet>323</a> <span class="kw">let </span>values = insert.values_body().unwrap();
<a href=#324 id=324 data-nosnippet>324</a> <span class="macro">assert_eq!</span>(values, <span class="macro">vec!</span>[<span class="macro">vec!</span>[Value::Placeholder(<span class="string">"DEFAULT"</span>.to_owned())]]);
<a href=#325 id=325 data-nosnippet>325</a> }
<a href=#326 id=326 data-nosnippet>326</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#327 id=327 data-nosnippet>327</a> }
<a href=#328 id=328 data-nosnippet>328</a> }
<a href=#329 id=329 data-nosnippet>329</a>
<a href=#330 id=330 data-nosnippet>330</a> <span class="attr">#[test]
<a href=#331 id=331 data-nosnippet>331</a> </span><span class="kw">fn </span>test_insert_value_with_quoted_string() {
<a href=#332 id=332 data-nosnippet>332</a> <span class="comment">// insert 'default'
<a href=#333 id=333 data-nosnippet>333</a> </span><span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES('default')"</span>;
<a href=#334 id=334 data-nosnippet>334</a> <span class="kw">let </span>stmt =
<a href=#335 id=335 data-nosnippet>335</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#336 id=336 data-nosnippet>336</a> .unwrap()
<a href=#337 id=337 data-nosnippet>337</a> .remove(<span class="number">0</span>);
<a href=#338 id=338 data-nosnippet>338</a> <span class="kw">match </span>stmt {
<a href=#339 id=339 data-nosnippet>339</a> Statement::Insert(insert) =&gt; {
<a href=#340 id=340 data-nosnippet>340</a> <span class="kw">let </span>values = insert.values_body().unwrap();
<a href=#341 id=341 data-nosnippet>341</a> <span class="macro">assert_eq!</span>(
<a href=#342 id=342 data-nosnippet>342</a> values,
<a href=#343 id=343 data-nosnippet>343</a> <span class="macro">vec!</span>[<span class="macro">vec!</span>[Value::SingleQuotedString(<span class="string">"default"</span>.to_owned())]]
<a href=#344 id=344 data-nosnippet>344</a> );
<a href=#345 id=345 data-nosnippet>345</a> }
<a href=#346 id=346 data-nosnippet>346</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#347 id=347 data-nosnippet>347</a> }
<a href=#348 id=348 data-nosnippet>348</a>
<a href=#349 id=349 data-nosnippet>349</a> <span class="comment">// insert "default". Treating double-quoted identifiers as strings.
<a href=#350 id=350 data-nosnippet>350</a> </span><span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES(\"default\")"</span>;
<a href=#351 id=351 data-nosnippet>351</a> <span class="kw">let </span>stmt =
<a href=#352 id=352 data-nosnippet>352</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#353 id=353 data-nosnippet>353</a> .unwrap()
<a href=#354 id=354 data-nosnippet>354</a> .remove(<span class="number">0</span>);
<a href=#355 id=355 data-nosnippet>355</a> <span class="kw">match </span>stmt {
<a href=#356 id=356 data-nosnippet>356</a> Statement::Insert(insert) =&gt; {
<a href=#357 id=357 data-nosnippet>357</a> <span class="kw">let </span>values = insert.values_body().unwrap();
<a href=#358 id=358 data-nosnippet>358</a> <span class="macro">assert_eq!</span>(
<a href=#359 id=359 data-nosnippet>359</a> values,
<a href=#360 id=360 data-nosnippet>360</a> <span class="macro">vec!</span>[<span class="macro">vec!</span>[Value::SingleQuotedString(<span class="string">"default"</span>.to_owned())]]
<a href=#361 id=361 data-nosnippet>361</a> );
<a href=#362 id=362 data-nosnippet>362</a> }
<a href=#363 id=363 data-nosnippet>363</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#364 id=364 data-nosnippet>364</a> }
<a href=#365 id=365 data-nosnippet>365</a>
<a href=#366 id=366 data-nosnippet>366</a> <span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table VALUES(`default`)"</span>;
<a href=#367 id=367 data-nosnippet>367</a> <span class="kw">let </span>stmt =
<a href=#368 id=368 data-nosnippet>368</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#369 id=369 data-nosnippet>369</a> .unwrap()
<a href=#370 id=370 data-nosnippet>370</a> .remove(<span class="number">0</span>);
<a href=#371 id=371 data-nosnippet>371</a> <span class="kw">match </span>stmt {
<a href=#372 id=372 data-nosnippet>372</a> Statement::Insert(insert) =&gt; {
<a href=#373 id=373 data-nosnippet>373</a> <span class="macro">assert!</span>(insert.values_body().is_err());
<a href=#374 id=374 data-nosnippet>374</a> }
<a href=#375 id=375 data-nosnippet>375</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#376 id=376 data-nosnippet>376</a> }
<a href=#377 id=377 data-nosnippet>377</a> }
<a href=#378 id=378 data-nosnippet>378</a>
<a href=#379 id=379 data-nosnippet>379</a> <span class="attr">#[test]
<a href=#380 id=380 data-nosnippet>380</a> </span><span class="kw">fn </span>test_insert_select() {
<a href=#381 id=381 data-nosnippet>381</a> <span class="kw">let </span>sql = <span class="string">"INSERT INTO my_table select * from other_table"</span>;
<a href=#382 id=382 data-nosnippet>382</a> <span class="kw">let </span>stmt =
<a href=#383 id=383 data-nosnippet>383</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#384 id=384 data-nosnippet>384</a> .unwrap()
<a href=#385 id=385 data-nosnippet>385</a> .remove(<span class="number">0</span>);
<a href=#386 id=386 data-nosnippet>386</a> <span class="kw">match </span>stmt {
<a href=#387 id=387 data-nosnippet>387</a> Statement::Insert(insert) =&gt; {
<a href=#388 id=388 data-nosnippet>388</a> <span class="kw">let </span>q = insert.query_body().unwrap().unwrap();
<a href=#389 id=389 data-nosnippet>389</a> <span class="macro">assert!</span>(insert.has_non_values_query_source());
<a href=#390 id=390 data-nosnippet>390</a> <span class="macro">assert!</span>(<span class="macro">matches!</span>(
<a href=#391 id=391 data-nosnippet>391</a> <span class="kw-2">&amp;</span>q.inner,
<a href=#392 id=392 data-nosnippet>392</a> sqlparser::ast::Query { body, .. }
<a href=#393 id=393 data-nosnippet>393</a> <span class="kw">if </span><span class="macro">matches!</span>(body.as_ref(), SetExpr::Select { .. })
<a href=#394 id=394 data-nosnippet>394</a> ));
<a href=#395 id=395 data-nosnippet>395</a> }
<a href=#396 id=396 data-nosnippet>396</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#397 id=397 data-nosnippet>397</a> }
<a href=#398 id=398 data-nosnippet>398</a> }
<a href=#399 id=399 data-nosnippet>399</a>
<a href=#400 id=400 data-nosnippet>400</a> <span class="attr">#[test]
<a href=#401 id=401 data-nosnippet>401</a> </span><span class="kw">fn </span>test_has_non_values_query_source() {
<a href=#402 id=402 data-nosnippet>402</a> <span class="kw">let </span>cases = [
<a href=#403 id=403 data-nosnippet>403</a> (<span class="string">"INSERT INTO my_table SELECT * FROM other_table"</span>, <span class="bool-val">true</span>),
<a href=#404 id=404 data-nosnippet>404</a> (
<a href=#405 id=405 data-nosnippet>405</a> <span class="string">"INSERT INTO my_table WITH cte AS (SELECT * FROM other_table) SELECT * FROM cte"</span>,
<a href=#406 id=406 data-nosnippet>406</a> <span class="bool-val">true</span>,
<a href=#407 id=407 data-nosnippet>407</a> ),
<a href=#408 id=408 data-nosnippet>408</a> (
<a href=#409 id=409 data-nosnippet>409</a> <span class="string">"INSERT INTO my_table SELECT * FROM t1 UNION ALL SELECT * FROM t2"</span>,
<a href=#410 id=410 data-nosnippet>410</a> <span class="bool-val">true</span>,
<a href=#411 id=411 data-nosnippet>411</a> ),
<a href=#412 id=412 data-nosnippet>412</a> (<span class="string">"INSERT INTO my_table VALUES(1)"</span>, <span class="bool-val">false</span>),
<a href=#413 id=413 data-nosnippet>413</a> (<span class="string">"INSERT INTO my_table VALUES(now())"</span>, <span class="bool-val">false</span>),
<a href=#414 id=414 data-nosnippet>414</a> (<span class="string">"INSERT INTO my_table VALUES(1 + 1)"</span>, <span class="bool-val">false</span>),
<a href=#415 id=415 data-nosnippet>415</a> ];
<a href=#416 id=416 data-nosnippet>416</a>
<a href=#417 id=417 data-nosnippet>417</a> <span class="kw">for </span>(sql, expected) <span class="kw">in </span>cases {
<a href=#418 id=418 data-nosnippet>418</a> <span class="kw">let </span>stmt = ParserContext::create_with_dialect(
<a href=#419 id=419 data-nosnippet>419</a> sql,
<a href=#420 id=420 data-nosnippet>420</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#421 id=421 data-nosnippet>421</a> ParseOptions::default(),
<a href=#422 id=422 data-nosnippet>422</a> )
<a href=#423 id=423 data-nosnippet>423</a> .unwrap()
<a href=#424 id=424 data-nosnippet>424</a> .remove(<span class="number">0</span>);
<a href=#425 id=425 data-nosnippet>425</a> <span class="kw">match </span>stmt {
<a href=#426 id=426 data-nosnippet>426</a> Statement::Insert(insert) =&gt; {
<a href=#427 id=427 data-nosnippet>427</a> <span class="macro">assert_eq!</span>(insert.has_non_values_query_source(), expected, <span class="string">"{sql}"</span>);
<a href=#428 id=428 data-nosnippet>428</a> }
<a href=#429 id=429 data-nosnippet>429</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#430 id=430 data-nosnippet>430</a> }
<a href=#431 id=431 data-nosnippet>431</a> }
<a href=#432 id=432 data-nosnippet>432</a> }
<a href=#433 id=433 data-nosnippet>433</a>}
</code></pre></div></section></main></body></html>
+41
View File
@@ -0,0 +1,41 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/kill.rs`."><title>kill.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>kill.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::{Display, Formatter};
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="doccomment">/// Arguments of `KILL` statements.
<a href=#21 id=21 data-nosnippet>21</a></span><span class="attr">#[derive(Debug, Clone, Eq, PartialEq, Visit, VisitMut, Serialize)]
<a href=#22 id=22 data-nosnippet>22</a></span><span class="kw">pub enum </span>Kill {
<a href=#23 id=23 data-nosnippet>23</a> <span class="doccomment">/// Kill a remote process id.
<a href=#24 id=24 data-nosnippet>24</a> </span>ProcessId(String),
<a href=#25 id=25 data-nosnippet>25</a> <span class="doccomment">/// Kill MySQL connection id.
<a href=#26 id=26 data-nosnippet>26</a> </span>ConnectionId(u32),
<a href=#27 id=27 data-nosnippet>27</a>}
<a href=#28 id=28 data-nosnippet>28</a>
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">impl </span>Display <span class="kw">for </span>Kill {
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#32 id=32 data-nosnippet>32</a> Kill::ProcessId(id) =&gt; {
<a href=#33 id=33 data-nosnippet>33</a> <span class="macro">write!</span>(f, <span class="string">"KILL {}"</span>, id)
<a href=#34 id=34 data-nosnippet>34</a> }
<a href=#35 id=35 data-nosnippet>35</a> Kill::ConnectionId(id) =&gt; {
<a href=#36 id=36 data-nosnippet>36</a> <span class="macro">write!</span>(f, <span class="string">"KILL QUERY {}"</span>, id)
<a href=#37 id=37 data-nosnippet>37</a> }
<a href=#38 id=38 data-nosnippet>38</a> }
<a href=#39 id=39 data-nosnippet>39</a> }
<a href=#40 id=40 data-nosnippet>40</a>}
</code></pre></div></section></main></body></html>
+306
View File
@@ -0,0 +1,306 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/option_map.rs`."><title>option_map.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>option_map.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::collections::{BTreeMap, HashMap};
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>std::ops::ControlFlow;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>common_base::secrets::{ExposeSecret, ExposeSecretMut, SecretString};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>either::Either;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>serde::Serialize;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>sqlparser::ast::{Visit, VisitMut, Visitor, VisitorMut};
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::util::OptionValue;
<a href=#24 id=24 data-nosnippet>24</a>
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">const </span>REDACTED_OPTIONS: [<span class="kw-2">&amp;</span>str; <span class="number">2</span>] = [<span class="string">"access_key_id"</span>, <span class="string">"secret_access_key"</span>];
<a href=#26 id=26 data-nosnippet>26</a>
<a href=#27 id=27 data-nosnippet>27</a><span class="doccomment">/// Options hashmap.
<a href=#28 id=28 data-nosnippet>28</a></span><span class="attr">#[derive(Clone, Debug, Default, Serialize)]
<a href=#29 id=29 data-nosnippet>29</a></span><span class="kw">pub struct </span>OptionMap {
<a href=#30 id=30 data-nosnippet>30</a> options: BTreeMap&lt;String, OptionValue&gt;,
<a href=#31 id=31 data-nosnippet>31</a> <span class="attr">#[serde(skip_serializing)]
<a href=#32 id=32 data-nosnippet>32</a> </span>secrets: BTreeMap&lt;String, SecretString&gt;,
<a href=#33 id=33 data-nosnippet>33</a>}
<a href=#34 id=34 data-nosnippet>34</a>
<a href=#35 id=35 data-nosnippet>35</a><span class="kw">impl </span>OptionMap {
<a href=#36 id=36 data-nosnippet>36</a> <span class="kw">pub fn </span>new&lt;I: IntoIterator&lt;Item = (String, OptionValue)&gt;&gt;(options: I) -&gt; <span class="self">Self </span>{
<a href=#37 id=37 data-nosnippet>37</a> <span class="kw">let </span>(secrets, options): (Vec&lt;<span class="kw">_</span>&gt;, Vec&lt;<span class="kw">_</span>&gt;) = options
<a href=#38 id=38 data-nosnippet>38</a> .into_iter()
<a href=#39 id=39 data-nosnippet>39</a> .partition(|(k, <span class="kw">_</span>)| REDACTED_OPTIONS.contains(<span class="kw-2">&amp;</span>k.as_str()));
<a href=#40 id=40 data-nosnippet>40</a> <span class="self">Self </span>{
<a href=#41 id=41 data-nosnippet>41</a> options: options.into_iter().collect(),
<a href=#42 id=42 data-nosnippet>42</a> secrets: secrets
<a href=#43 id=43 data-nosnippet>43</a> .into_iter()
<a href=#44 id=44 data-nosnippet>44</a> .filter_map(|(k, v)| {
<a href=#45 id=45 data-nosnippet>45</a> v.as_string()
<a href=#46 id=46 data-nosnippet>46</a> .map(|v| (k, SecretString::new(Box::new(v.to_string()))))
<a href=#47 id=47 data-nosnippet>47</a> })
<a href=#48 id=48 data-nosnippet>48</a> .collect(),
<a href=#49 id=49 data-nosnippet>49</a> }
<a href=#50 id=50 data-nosnippet>50</a> }
<a href=#51 id=51 data-nosnippet>51</a>
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">pub fn </span>from_filtered_string_map(
<a href=#53 id=53 data-nosnippet>53</a> options: <span class="kw-2">&amp;</span>HashMap&lt;String, String&gt;,
<a href=#54 id=54 data-nosnippet>54</a> hidden_keys: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span>str],
<a href=#55 id=55 data-nosnippet>55</a> ) -&gt; <span class="self">Self </span>{
<a href=#56 id=56 data-nosnippet>56</a> <span class="self">Self</span>::from(
<a href=#57 id=57 data-nosnippet>57</a> options
<a href=#58 id=58 data-nosnippet>58</a> .iter()
<a href=#59 id=59 data-nosnippet>59</a> .filter(|(key, <span class="kw">_</span>)| !hidden_keys.contains(<span class="kw-2">&amp;</span>key.as_str()))
<a href=#60 id=60 data-nosnippet>60</a> .map(|(key, value)| (key.clone(), value.clone())),
<a href=#61 id=61 data-nosnippet>61</a> )
<a href=#62 id=62 data-nosnippet>62</a> }
<a href=#63 id=63 data-nosnippet>63</a>
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">pub fn </span>insert(<span class="kw-2">&amp;mut </span><span class="self">self</span>, k: String, v: String) {
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">if </span>REDACTED_OPTIONS.contains(<span class="kw-2">&amp;</span>k.as_str()) {
<a href=#66 id=66 data-nosnippet>66</a> <span class="self">self</span>.secrets.insert(k, SecretString::new(Box::new(v)));
<a href=#67 id=67 data-nosnippet>67</a> } <span class="kw">else </span>{
<a href=#68 id=68 data-nosnippet>68</a> <span class="self">self</span>.options.insert(k, v.into());
<a href=#69 id=69 data-nosnippet>69</a> }
<a href=#70 id=70 data-nosnippet>70</a> }
<a href=#71 id=71 data-nosnippet>71</a>
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">pub fn </span>insert_options(<span class="kw-2">&amp;mut </span><span class="self">self</span>, key: <span class="kw-2">&amp;</span>str, value: OptionValue) {
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">if </span>REDACTED_OPTIONS.contains(<span class="kw-2">&amp;</span>key) {
<a href=#74 id=74 data-nosnippet>74</a> <span class="self">self</span>.secrets.insert(
<a href=#75 id=75 data-nosnippet>75</a> key.to_string(),
<a href=#76 id=76 data-nosnippet>76</a> SecretString::new(Box::new(value.to_string())),
<a href=#77 id=77 data-nosnippet>77</a> );
<a href=#78 id=78 data-nosnippet>78</a> } <span class="kw">else </span>{
<a href=#79 id=79 data-nosnippet>79</a> <span class="self">self</span>.options.insert(key.to_string(), value);
<a href=#80 id=80 data-nosnippet>80</a> }
<a href=#81 id=81 data-nosnippet>81</a> }
<a href=#82 id=82 data-nosnippet>82</a>
<a href=#83 id=83 data-nosnippet>83</a> <span class="kw">pub fn </span>get(<span class="kw-2">&amp;</span><span class="self">self</span>, k: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>str&gt; {
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(value) = <span class="self">self</span>.options.get(k) {
<a href=#85 id=85 data-nosnippet>85</a> value.as_string()
<a href=#86 id=86 data-nosnippet>86</a> } <span class="kw">else if let </span><span class="prelude-val">Some</span>(value) = <span class="self">self</span>.secrets.get(k) {
<a href=#87 id=87 data-nosnippet>87</a> <span class="prelude-val">Some</span>(value.expose_secret())
<a href=#88 id=88 data-nosnippet>88</a> } <span class="kw">else </span>{
<a href=#89 id=89 data-nosnippet>89</a> <span class="prelude-val">None
<a href=#90 id=90 data-nosnippet>90</a> </span>}
<a href=#91 id=91 data-nosnippet>91</a> }
<a href=#92 id=92 data-nosnippet>92</a>
<a href=#93 id=93 data-nosnippet>93</a> <span class="kw">pub fn </span>value(<span class="kw-2">&amp;</span><span class="self">self</span>, k: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>OptionValue&gt; {
<a href=#94 id=94 data-nosnippet>94</a> <span class="self">self</span>.options.get(k)
<a href=#95 id=95 data-nosnippet>95</a> }
<a href=#96 id=96 data-nosnippet>96</a>
<a href=#97 id=97 data-nosnippet>97</a> <span class="kw">pub fn </span>is_empty(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#98 id=98 data-nosnippet>98</a> <span class="self">self</span>.options.is_empty() &amp;&amp; <span class="self">self</span>.secrets.is_empty()
<a href=#99 id=99 data-nosnippet>99</a> }
<a href=#100 id=100 data-nosnippet>100</a>
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">pub fn </span>len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
<a href=#102 id=102 data-nosnippet>102</a> <span class="self">self</span>.options.len() + <span class="self">self</span>.secrets.len()
<a href=#103 id=103 data-nosnippet>103</a> }
<a href=#104 id=104 data-nosnippet>104</a>
<a href=#105 id=105 data-nosnippet>105</a> <span class="doccomment">/// Convert the option map to a string map.
<a href=#106 id=106 data-nosnippet>106</a> ///
<a href=#107 id=107 data-nosnippet>107</a> /// Notes: Not all values can be converted to a string, refer to [OptionValue::expr_as_string] for more details.
<a href=#108 id=108 data-nosnippet>108</a> </span><span class="kw">pub fn </span>to_str_map(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; HashMap&lt;<span class="kw-2">&amp;</span>str, <span class="kw-2">&amp;</span>str&gt; {
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw">let </span><span class="kw-2">mut </span>map = HashMap::with_capacity(<span class="self">self</span>.len());
<a href=#110 id=110 data-nosnippet>110</a> map.extend(
<a href=#111 id=111 data-nosnippet>111</a> <span class="self">self</span>.options
<a href=#112 id=112 data-nosnippet>112</a> .iter()
<a href=#113 id=113 data-nosnippet>113</a> .filter_map(|(k, v)| v.as_string().map(|v| (k.as_str(), v))),
<a href=#114 id=114 data-nosnippet>114</a> );
<a href=#115 id=115 data-nosnippet>115</a> map.extend(
<a href=#116 id=116 data-nosnippet>116</a> <span class="self">self</span>.secrets
<a href=#117 id=117 data-nosnippet>117</a> .iter()
<a href=#118 id=118 data-nosnippet>118</a> .map(|(k, v)| (k.as_str(), v.expose_secret().as_str())),
<a href=#119 id=119 data-nosnippet>119</a> );
<a href=#120 id=120 data-nosnippet>120</a> map
<a href=#121 id=121 data-nosnippet>121</a> }
<a href=#122 id=122 data-nosnippet>122</a>
<a href=#123 id=123 data-nosnippet>123</a> <span class="doccomment">/// Convert the option map to a string map.
<a href=#124 id=124 data-nosnippet>124</a> ///
<a href=#125 id=125 data-nosnippet>125</a> /// Notes: Not all values can be converted to a string, refer to [OptionValue::expr_as_string] for more details.
<a href=#126 id=126 data-nosnippet>126</a> </span><span class="kw">pub fn </span>into_map(<span class="self">self</span>) -&gt; HashMap&lt;String, String&gt; {
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">let </span><span class="kw-2">mut </span>map = HashMap::with_capacity(<span class="self">self</span>.len());
<a href=#128 id=128 data-nosnippet>128</a> map.extend(
<a href=#129 id=129 data-nosnippet>129</a> <span class="self">self</span>.options
<a href=#130 id=130 data-nosnippet>130</a> .into_iter()
<a href=#131 id=131 data-nosnippet>131</a> .filter_map(|(k, v)| v.as_string().map(|v| (k, v.to_string()))),
<a href=#132 id=132 data-nosnippet>132</a> );
<a href=#133 id=133 data-nosnippet>133</a> map.extend(
<a href=#134 id=134 data-nosnippet>134</a> <span class="self">self</span>.secrets
<a href=#135 id=135 data-nosnippet>135</a> .into_iter()
<a href=#136 id=136 data-nosnippet>136</a> .map(|(k, v)| (k, v.expose_secret().clone())),
<a href=#137 id=137 data-nosnippet>137</a> );
<a href=#138 id=138 data-nosnippet>138</a> map
<a href=#139 id=139 data-nosnippet>139</a> }
<a href=#140 id=140 data-nosnippet>140</a>
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">pub fn </span>kv_pairs(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;String&gt; {
<a href=#142 id=142 data-nosnippet>142</a> <span class="self">self</span>.sql_pairs(<span class="bool-val">false</span>).map(|pair| pair.to_string()).collect()
<a href=#143 id=143 data-nosnippet>143</a> }
<a href=#144 id=144 data-nosnippet>144</a>
<a href=#145 id=145 data-nosnippet>145</a> <span class="doccomment">/// Streams the same pairs as `kv_pairs`, or all actual values for size validation.
<a href=#146 id=146 data-nosnippet>146</a> </span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>write_sql(
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw-2">&amp;</span><span class="self">self</span>,
<a href=#148 id=148 data-nosnippet>148</a> f: <span class="kw-2">&amp;mut </span><span class="kw">dyn </span>std::fmt::Write,
<a href=#149 id=149 data-nosnippet>149</a> separator: <span class="kw-2">&amp;</span>str,
<a href=#150 id=150 data-nosnippet>150</a> prefix: <span class="kw-2">&amp;</span>str,
<a href=#151 id=151 data-nosnippet>151</a> complete: bool,
<a href=#152 id=152 data-nosnippet>152</a> ) -&gt; std::fmt::Result {
<a href=#153 id=153 data-nosnippet>153</a> <span class="kw">for </span>(index, pair) <span class="kw">in </span><span class="self">self</span>.sql_pairs(complete).enumerate() {
<a href=#154 id=154 data-nosnippet>154</a> <span class="kw">if </span>index &gt; <span class="number">0 </span>{
<a href=#155 id=155 data-nosnippet>155</a> f.write_str(separator)<span class="question-mark">?</span>;
<a href=#156 id=156 data-nosnippet>156</a> }
<a href=#157 id=157 data-nosnippet>157</a> <span class="macro">write!</span>(f, <span class="string">"{prefix}{pair}"</span>)<span class="question-mark">?</span>;
<a href=#158 id=158 data-nosnippet>158</a> }
<a href=#159 id=159 data-nosnippet>159</a> <span class="prelude-val">Ok</span>(())
<a href=#160 id=160 data-nosnippet>160</a> }
<a href=#161 id=161 data-nosnippet>161</a>
<a href=#162 id=162 data-nosnippet>162</a> <span class="kw">fn </span>sql_pairs(<span class="kw-2">&amp;</span><span class="self">self</span>, complete: bool) -&gt; <span class="kw">impl </span>Iterator&lt;Item = SqlPair&lt;<span class="lifetime">'_</span>&gt;&gt; {
<a href=#163 id=163 data-nosnippet>163</a> <span class="kw">let </span>options = <span class="self">self</span>.options.iter().filter_map(<span class="kw">move </span>|(key, value)| {
<a href=#164 id=164 data-nosnippet>164</a> <span class="kw">let </span>value = <span class="kw">match </span>value.as_string() {
<a href=#165 id=165 data-nosnippet>165</a> <span class="prelude-val">Some</span>(value) =&gt; Either::Right(value),
<a href=#166 id=166 data-nosnippet>166</a> <span class="prelude-val">None </span><span class="kw">if </span>complete =&gt; Either::Left(value),
<a href=#167 id=167 data-nosnippet>167</a> <span class="prelude-val">None </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
<a href=#168 id=168 data-nosnippet>168</a> };
<a href=#169 id=169 data-nosnippet>169</a> <span class="prelude-val">Some</span>(SqlPair { key, value })
<a href=#170 id=170 data-nosnippet>170</a> });
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">let </span>secrets = <span class="self">self</span>.secrets.iter().map(<span class="kw">move </span>|(key, value)| SqlPair {
<a href=#172 id=172 data-nosnippet>172</a> key,
<a href=#173 id=173 data-nosnippet>173</a> value: Either::Right(<span class="kw">if </span>complete {
<a href=#174 id=174 data-nosnippet>174</a> value.expose_secret()
<a href=#175 id=175 data-nosnippet>175</a> } <span class="kw">else </span>{
<a href=#176 id=176 data-nosnippet>176</a> <span class="string">"******"
<a href=#177 id=177 data-nosnippet>177</a> </span>}),
<a href=#178 id=178 data-nosnippet>178</a> });
<a href=#179 id=179 data-nosnippet>179</a> options.chain(secrets)
<a href=#180 id=180 data-nosnippet>180</a> }
<a href=#181 id=181 data-nosnippet>181</a>
<a href=#182 id=182 data-nosnippet>182</a> <span class="kw">pub fn </span>entries(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw">impl </span>Iterator&lt;Item = (<span class="kw-2">&amp;</span>str, Either&lt;<span class="kw-2">&amp;</span>OptionValue, <span class="kw-2">&amp;</span>str&gt;)&gt; {
<a href=#183 id=183 data-nosnippet>183</a> <span class="kw">let </span>options = <span class="self">self
<a href=#184 id=184 data-nosnippet>184</a> </span>.options
<a href=#185 id=185 data-nosnippet>185</a> .iter()
<a href=#186 id=186 data-nosnippet>186</a> .map(|(k, v)| (k.as_str(), Either::Left(v)));
<a href=#187 id=187 data-nosnippet>187</a> <span class="kw">let </span>secrets = <span class="self">self
<a href=#188 id=188 data-nosnippet>188</a> </span>.secrets
<a href=#189 id=189 data-nosnippet>189</a> .keys()
<a href=#190 id=190 data-nosnippet>190</a> .map(|k| (k.as_str(), Either::Right(<span class="string">"******"</span>)));
<a href=#191 id=191 data-nosnippet>191</a> std::iter::chain(options, secrets)
<a href=#192 id=192 data-nosnippet>192</a> }
<a href=#193 id=193 data-nosnippet>193</a>}
<a href=#194 id=194 data-nosnippet>194</a>
<a href=#195 id=195 data-nosnippet>195</a><span class="kw">struct </span>SqlPair&lt;<span class="lifetime">'a</span>&gt; {
<a href=#196 id=196 data-nosnippet>196</a> key: <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str,
<a href=#197 id=197 data-nosnippet>197</a> value: Either&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>OptionValue, <span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt;,
<a href=#198 id=198 data-nosnippet>198</a>}
<a href=#199 id=199 data-nosnippet>199</a>
<a href=#200 id=200 data-nosnippet>200</a><span class="kw">impl </span>std::fmt::Display <span class="kw">for </span>SqlPair&lt;<span class="lifetime">'_</span>&gt; {
<a href=#201 id=201 data-nosnippet>201</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#202 id=202 data-nosnippet>202</a> <span class="kw">if </span><span class="self">self</span>.key.contains(<span class="string">'.'</span>) {
<a href=#203 id=203 data-nosnippet>203</a> <span class="macro">write!</span>(f, <span class="string">"'{}'"</span>, <span class="self">self</span>.key)<span class="question-mark">?</span>;
<a href=#204 id=204 data-nosnippet>204</a> } <span class="kw">else </span>{
<a href=#205 id=205 data-nosnippet>205</a> f.write_str(<span class="self">self</span>.key)<span class="question-mark">?</span>;
<a href=#206 id=206 data-nosnippet>206</a> }
<a href=#207 id=207 data-nosnippet>207</a> <span class="kw">match </span><span class="self">self</span>.value {
<a href=#208 id=208 data-nosnippet>208</a> Either::Left(value) =&gt; <span class="macro">write!</span>(f, <span class="string">" = {value}"</span>),
<a href=#209 id=209 data-nosnippet>209</a> Either::Right(value) =&gt; <span class="macro">write!</span>(f, <span class="string">" = '{}'"</span>, value.escape_debug()),
<a href=#210 id=210 data-nosnippet>210</a> }
<a href=#211 id=211 data-nosnippet>211</a> }
<a href=#212 id=212 data-nosnippet>212</a>}
<a href=#213 id=213 data-nosnippet>213</a>
<a href=#214 id=214 data-nosnippet>214</a><span class="kw">impl</span>&lt;I: IntoIterator&lt;Item = (String, String)&gt;&gt; From&lt;I&gt; <span class="kw">for </span>OptionMap {
<a href=#215 id=215 data-nosnippet>215</a> <span class="kw">fn </span>from(value: I) -&gt; <span class="self">Self </span>{
<a href=#216 id=216 data-nosnippet>216</a> <span class="kw">let </span><span class="kw-2">mut </span>result = OptionMap::default();
<a href=#217 id=217 data-nosnippet>217</a> <span class="kw">for </span>(k, v) <span class="kw">in </span>value {
<a href=#218 id=218 data-nosnippet>218</a> result.insert(k, v);
<a href=#219 id=219 data-nosnippet>219</a> }
<a href=#220 id=220 data-nosnippet>220</a> result
<a href=#221 id=221 data-nosnippet>221</a> }
<a href=#222 id=222 data-nosnippet>222</a>}
<a href=#223 id=223 data-nosnippet>223</a>
<a href=#224 id=224 data-nosnippet>224</a><span class="kw">impl </span>PartialEq <span class="kw">for </span>OptionMap {
<a href=#225 id=225 data-nosnippet>225</a> <span class="kw">fn </span>eq(<span class="kw-2">&amp;</span><span class="self">self</span>, other: <span class="kw-2">&amp;</span><span class="self">Self</span>) -&gt; bool {
<a href=#226 id=226 data-nosnippet>226</a> <span class="kw">if </span><span class="self">self</span>.options.ne(<span class="kw-2">&amp;</span>other.options) {
<a href=#227 id=227 data-nosnippet>227</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#228 id=228 data-nosnippet>228</a> }
<a href=#229 id=229 data-nosnippet>229</a>
<a href=#230 id=230 data-nosnippet>230</a> <span class="kw">if </span><span class="self">self</span>.secrets.len() != other.secrets.len() {
<a href=#231 id=231 data-nosnippet>231</a> <span class="kw">return </span><span class="bool-val">false</span>;
<a href=#232 id=232 data-nosnippet>232</a> }
<a href=#233 id=233 data-nosnippet>233</a>
<a href=#234 id=234 data-nosnippet>234</a> <span class="self">self</span>.secrets.iter().all(|(key, value)| {
<a href=#235 id=235 data-nosnippet>235</a> other
<a href=#236 id=236 data-nosnippet>236</a> .secrets
<a href=#237 id=237 data-nosnippet>237</a> .get(key)
<a href=#238 id=238 data-nosnippet>238</a> .is_some_and(|v| value.expose_secret() == v.expose_secret())
<a href=#239 id=239 data-nosnippet>239</a> })
<a href=#240 id=240 data-nosnippet>240</a> }
<a href=#241 id=241 data-nosnippet>241</a>}
<a href=#242 id=242 data-nosnippet>242</a>
<a href=#243 id=243 data-nosnippet>243</a><span class="kw">impl </span>Eq <span class="kw">for </span>OptionMap {}
<a href=#244 id=244 data-nosnippet>244</a>
<a href=#245 id=245 data-nosnippet>245</a><span class="kw">impl </span>Visit <span class="kw">for </span>OptionMap {
<a href=#246 id=246 data-nosnippet>246</a> <span class="kw">fn </span>visit&lt;V: Visitor&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, visitor: <span class="kw-2">&amp;mut </span>V) -&gt; ControlFlow&lt;V::Break&gt; {
<a href=#247 id=247 data-nosnippet>247</a> <span class="kw">for </span>(k, v) <span class="kw">in </span><span class="kw-2">&amp;</span><span class="self">self</span>.options {
<a href=#248 id=248 data-nosnippet>248</a> k.visit(visitor)<span class="question-mark">?</span>;
<a href=#249 id=249 data-nosnippet>249</a> v.visit(visitor)<span class="question-mark">?</span>;
<a href=#250 id=250 data-nosnippet>250</a> }
<a href=#251 id=251 data-nosnippet>251</a> <span class="kw">for </span>(k, v) <span class="kw">in </span><span class="kw-2">&amp;</span><span class="self">self</span>.secrets {
<a href=#252 id=252 data-nosnippet>252</a> k.visit(visitor)<span class="question-mark">?</span>;
<a href=#253 id=253 data-nosnippet>253</a> v.expose_secret().visit(visitor)<span class="question-mark">?</span>;
<a href=#254 id=254 data-nosnippet>254</a> }
<a href=#255 id=255 data-nosnippet>255</a> ControlFlow::Continue(())
<a href=#256 id=256 data-nosnippet>256</a> }
<a href=#257 id=257 data-nosnippet>257</a>}
<a href=#258 id=258 data-nosnippet>258</a>
<a href=#259 id=259 data-nosnippet>259</a><span class="kw">impl </span>VisitMut <span class="kw">for </span>OptionMap {
<a href=#260 id=260 data-nosnippet>260</a> <span class="kw">fn </span>visit&lt;V: VisitorMut&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, visitor: <span class="kw-2">&amp;mut </span>V) -&gt; ControlFlow&lt;V::Break&gt; {
<a href=#261 id=261 data-nosnippet>261</a> <span class="kw">for </span>v <span class="kw">in </span><span class="self">self</span>.options.values_mut() {
<a href=#262 id=262 data-nosnippet>262</a> v.visit(visitor)<span class="question-mark">?</span>;
<a href=#263 id=263 data-nosnippet>263</a> }
<a href=#264 id=264 data-nosnippet>264</a> <span class="kw">for </span>v <span class="kw">in </span><span class="self">self</span>.secrets.values_mut() {
<a href=#265 id=265 data-nosnippet>265</a> v.expose_secret_mut().visit(visitor)<span class="question-mark">?</span>;
<a href=#266 id=266 data-nosnippet>266</a> }
<a href=#267 id=267 data-nosnippet>267</a> ControlFlow::Continue(())
<a href=#268 id=268 data-nosnippet>268</a> }
<a href=#269 id=269 data-nosnippet>269</a>}
<a href=#270 id=270 data-nosnippet>270</a>
<a href=#271 id=271 data-nosnippet>271</a><span class="attr">#[cfg(test)]
<a href=#272 id=272 data-nosnippet>272</a></span><span class="kw">mod </span>tests {
<a href=#273 id=273 data-nosnippet>273</a> <span class="kw">use </span>std::collections::HashMap;
<a href=#274 id=274 data-nosnippet>274</a>
<a href=#275 id=275 data-nosnippet>275</a> <span class="kw">use </span><span class="kw">crate</span>::statements::OptionMap;
<a href=#276 id=276 data-nosnippet>276</a>
<a href=#277 id=277 data-nosnippet>277</a> <span class="attr">#[test]
<a href=#278 id=278 data-nosnippet>278</a> </span><span class="kw">fn </span>test_format() {
<a href=#279 id=279 data-nosnippet>279</a> <span class="kw">let </span><span class="kw-2">mut </span>map = OptionMap::default();
<a href=#280 id=280 data-nosnippet>280</a> map.insert(<span class="string">"comment"</span>.to_string(), <span class="string">"中文comment"</span>.to_string());
<a href=#281 id=281 data-nosnippet>281</a> <span class="macro">assert_eq!</span>(<span class="string">"comment = '中文comment'"</span>, map.kv_pairs()[<span class="number">0</span>]);
<a href=#282 id=282 data-nosnippet>282</a>
<a href=#283 id=283 data-nosnippet>283</a> <span class="kw">let </span><span class="kw-2">mut </span>map = OptionMap::default();
<a href=#284 id=284 data-nosnippet>284</a> map.insert(<span class="string">"a.b"</span>.to_string(), <span class="string">"中文comment"</span>.to_string());
<a href=#285 id=285 data-nosnippet>285</a> <span class="macro">assert_eq!</span>(<span class="string">"'a.b' = '中文comment'"</span>, map.kv_pairs()[<span class="number">0</span>]);
<a href=#286 id=286 data-nosnippet>286</a>
<a href=#287 id=287 data-nosnippet>287</a> <span class="kw">let </span><span class="kw-2">mut </span>map = OptionMap::default();
<a href=#288 id=288 data-nosnippet>288</a> map.insert(<span class="string">"a.b"</span>.to_string(), <span class="string">"中文comment\n"</span>.to_string());
<a href=#289 id=289 data-nosnippet>289</a> <span class="macro">assert_eq!</span>(<span class="string">"'a.b' = '中文comment\\n'"</span>, map.kv_pairs()[<span class="number">0</span>]);
<a href=#290 id=290 data-nosnippet>290</a> }
<a href=#291 id=291 data-nosnippet>291</a>
<a href=#292 id=292 data-nosnippet>292</a> <span class="attr">#[test]
<a href=#293 id=293 data-nosnippet>293</a> </span><span class="kw">fn </span>test_from_filtered_string_map() {
<a href=#294 id=294 data-nosnippet>294</a> <span class="kw">let </span>map = OptionMap::from_filtered_string_map(
<a href=#295 id=295 data-nosnippet>295</a> <span class="kw-2">&amp;</span>HashMap::from([
<a href=#296 id=296 data-nosnippet>296</a> (<span class="string">"visible"</span>.to_string(), <span class="string">"1"</span>.to_string()),
<a href=#297 id=297 data-nosnippet>297</a> (<span class="string">"hidden"</span>.to_string(), <span class="string">"2"</span>.to_string()),
<a href=#298 id=298 data-nosnippet>298</a> ]),
<a href=#299 id=299 data-nosnippet>299</a> <span class="kw-2">&amp;</span>[<span class="string">"hidden"</span>],
<a href=#300 id=300 data-nosnippet>300</a> );
<a href=#301 id=301 data-nosnippet>301</a>
<a href=#302 id=302 data-nosnippet>302</a> <span class="macro">assert_eq!</span>(map.get(<span class="string">"visible"</span>), <span class="prelude-val">Some</span>(<span class="string">"1"</span>));
<a href=#303 id=303 data-nosnippet>303</a> <span class="macro">assert_eq!</span>(map.get(<span class="string">"hidden"</span>), <span class="prelude-val">None</span>);
<a href=#304 id=304 data-nosnippet>304</a> }
<a href=#305 id=305 data-nosnippet>305</a>}
</code></pre></div></section></main></body></html>
+119
View File
@@ -0,0 +1,119 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/query.rs`."><title>query.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>query.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::Query <span class="kw">as </span>SpQuery;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span><span class="kw">crate</span>::error::Error;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::parsers::with_tql_parser::HybridCteWith;
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="doccomment">/// A wrapper around [`Query`] from sqlparser-rs to add support for hybrid CTEs
<a href=#25 id=25 data-nosnippet>25</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#26 id=26 data-nosnippet>26</a></span><span class="kw">pub struct </span>Query {
<a href=#27 id=27 data-nosnippet>27</a> <span class="kw">pub </span>inner: SpQuery,
<a href=#28 id=28 data-nosnippet>28</a> <span class="doccomment">/// Hybrid CTE containing both SQL and TQL CTEs
<a href=#29 id=29 data-nosnippet>29</a> </span><span class="kw">pub </span>hybrid_cte: <span class="prelude-ty">Option</span>&lt;HybridCteWith&gt;,
<a href=#30 id=30 data-nosnippet>30</a>}
<a href=#31 id=31 data-nosnippet>31</a>
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">impl </span>TryFrom&lt;SpQuery&gt; <span class="kw">for </span>Query {
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">type </span>Error = Error;
<a href=#34 id=34 data-nosnippet>34</a>
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">fn </span>try_from(inner: SpQuery) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, <span class="self">Self</span>::Error&gt; {
<a href=#36 id=36 data-nosnippet>36</a> <span class="prelude-val">Ok</span>(<span class="self">Self </span>{
<a href=#37 id=37 data-nosnippet>37</a> inner,
<a href=#38 id=38 data-nosnippet>38</a> hybrid_cte: <span class="prelude-val">None</span>,
<a href=#39 id=39 data-nosnippet>39</a> })
<a href=#40 id=40 data-nosnippet>40</a> }
<a href=#41 id=41 data-nosnippet>41</a>}
<a href=#42 id=42 data-nosnippet>42</a>
<a href=#43 id=43 data-nosnippet>43</a><span class="kw">impl </span>TryFrom&lt;Query&gt; <span class="kw">for </span>SpQuery {
<a href=#44 id=44 data-nosnippet>44</a> <span class="kw">type </span>Error = Error;
<a href=#45 id=45 data-nosnippet>45</a>
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">fn </span>try_from(value: Query) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, <span class="self">Self</span>::Error&gt; {
<a href=#47 id=47 data-nosnippet>47</a> <span class="prelude-val">Ok</span>(value.inner)
<a href=#48 id=48 data-nosnippet>48</a> }
<a href=#49 id=49 data-nosnippet>49</a>}
<a href=#50 id=50 data-nosnippet>50</a>
<a href=#51 id=51 data-nosnippet>51</a><span class="kw">impl </span>fmt::Display <span class="kw">for </span>Query {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(hybrid_cte) = <span class="kw-2">&amp;</span><span class="self">self</span>.hybrid_cte {
<a href=#54 id=54 data-nosnippet>54</a> <span class="comment">// Delegate the WITH clause rendering to `HybridCteWith`
<a href=#55 id=55 data-nosnippet>55</a> </span><span class="macro">write!</span>(f, <span class="string">"{} "</span>, hybrid_cte)<span class="question-mark">?</span>;
<a href=#56 id=56 data-nosnippet>56</a>
<a href=#57 id=57 data-nosnippet>57</a> <span class="comment">// Display the main query without its WITH clause since we handled it above
<a href=#58 id=58 data-nosnippet>58</a> </span><span class="kw">let </span><span class="kw-2">mut </span>main_query = <span class="self">self</span>.inner.clone();
<a href=#59 id=59 data-nosnippet>59</a> main_query.with = <span class="prelude-val">None</span>;
<a href=#60 id=60 data-nosnippet>60</a> <span class="macro">write!</span>(f, <span class="string">"{}"</span>, main_query)
<a href=#61 id=61 data-nosnippet>61</a> } <span class="kw">else </span>{
<a href=#62 id=62 data-nosnippet>62</a> <span class="macro">write!</span>(f, <span class="string">"{}"</span>, <span class="self">self</span>.inner)
<a href=#63 id=63 data-nosnippet>63</a> }
<a href=#64 id=64 data-nosnippet>64</a> }
<a href=#65 id=65 data-nosnippet>65</a>}
<a href=#66 id=66 data-nosnippet>66</a>
<a href=#67 id=67 data-nosnippet>67</a><span class="attr">#[cfg(test)]
<a href=#68 id=68 data-nosnippet>68</a></span><span class="kw">mod </span>test {
<a href=#69 id=69 data-nosnippet>69</a>
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">use </span><span class="kw">super</span>::Query;
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#74 id=74 data-nosnippet>74</a>
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">fn </span>create_query(sql: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;Box&lt;Query&gt;&gt; {
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw">match </span>ParserContext::create_with_dialect(
<a href=#77 id=77 data-nosnippet>77</a> sql,
<a href=#78 id=78 data-nosnippet>78</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#79 id=79 data-nosnippet>79</a> ParseOptions::default(),
<a href=#80 id=80 data-nosnippet>80</a> )
<a href=#81 id=81 data-nosnippet>81</a> .unwrap()
<a href=#82 id=82 data-nosnippet>82</a> .remove(<span class="number">0</span>)
<a href=#83 id=83 data-nosnippet>83</a> {
<a href=#84 id=84 data-nosnippet>84</a> Statement::Query(query) =&gt; <span class="prelude-val">Some</span>(query),
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#86 id=86 data-nosnippet>86</a> }
<a href=#87 id=87 data-nosnippet>87</a> }
<a href=#88 id=88 data-nosnippet>88</a>
<a href=#89 id=89 data-nosnippet>89</a> <span class="attr">#[test]
<a href=#90 id=90 data-nosnippet>90</a> </span><span class="kw">fn </span>test_query_display() {
<a href=#91 id=91 data-nosnippet>91</a> <span class="macro">assert_eq!</span>(
<a href=#92 id=92 data-nosnippet>92</a> create_query(<span class="string">"select * from abc where x = 1 and y = 7"</span>)
<a href=#93 id=93 data-nosnippet>93</a> .unwrap()
<a href=#94 id=94 data-nosnippet>94</a> .to_string(),
<a href=#95 id=95 data-nosnippet>95</a> <span class="string">"SELECT * FROM abc WHERE x = 1 AND y = 7"
<a href=#96 id=96 data-nosnippet>96</a> </span>);
<a href=#97 id=97 data-nosnippet>97</a> <span class="macro">assert_eq!</span>(
<a href=#98 id=98 data-nosnippet>98</a> create_query(
<a href=#99 id=99 data-nosnippet>99</a> <span class="string">"select * from abc left join bcd where abc.a = 1 and bcd.d = 7 and abc.id = bcd.id"
<a href=#100 id=100 data-nosnippet>100</a> </span>)
<a href=#101 id=101 data-nosnippet>101</a> .unwrap()
<a href=#102 id=102 data-nosnippet>102</a> .to_string(),
<a href=#103 id=103 data-nosnippet>103</a> <span class="string">"SELECT * FROM abc LEFT JOIN bcd WHERE abc.a = 1 AND bcd.d = 7 AND abc.id = bcd.id"
<a href=#104 id=104 data-nosnippet>104</a> </span>);
<a href=#105 id=105 data-nosnippet>105</a> <span class="macro">assert_eq!</span>(
<a href=#106 id=106 data-nosnippet>106</a> create_query(<span class="string">"WITH tql_cte AS (TQL EVAL (0, 100, '5s') up) SELECT * FROM tql_cte"</span>)
<a href=#107 id=107 data-nosnippet>107</a> .unwrap()
<a href=#108 id=108 data-nosnippet>108</a> .to_string(),
<a href=#109 id=109 data-nosnippet>109</a> <span class="string">"WITH tql_cte AS (TQL EVAL (0, 100, '5s') up) SELECT * FROM tql_cte"
<a href=#110 id=110 data-nosnippet>110</a> </span>);
<a href=#111 id=111 data-nosnippet>111</a> <span class="macro">assert_eq!</span>(
<a href=#112 id=112 data-nosnippet>112</a> create_query(<span class="string">"WITH sql_cte AS (SELECT 1) SELECT * FROM sql_cte"</span>)
<a href=#113 id=113 data-nosnippet>113</a> .unwrap()
<a href=#114 id=114 data-nosnippet>114</a> .to_string(),
<a href=#115 id=115 data-nosnippet>115</a> <span class="string">"WITH sql_cte AS (SELECT 1) SELECT * FROM sql_cte"
<a href=#116 id=116 data-nosnippet>116</a> </span>);
<a href=#117 id=117 data-nosnippet>117</a> }
<a href=#118 id=118 data-nosnippet>118</a>}
</code></pre></div></section></main></body></html>
+117
View File
@@ -0,0 +1,117 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/set_variables.rs`."><title>set_variables.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>set_variables.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::{Expr, ObjectName, ObjectNamePart, Value, ValueWithSpan};
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="doccomment">/// SET variables statement.
<a href=#22 id=22 data-nosnippet>22</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#23 id=23 data-nosnippet>23</a></span><span class="kw">pub struct </span>SetVariables {
<a href=#24 id=24 data-nosnippet>24</a> <span class="kw">pub </span>variable: ObjectName,
<a href=#25 id=25 data-nosnippet>25</a> <span class="kw">pub </span>value: Vec&lt;Expr&gt;,
<a href=#26 id=26 data-nosnippet>26</a>}
<a href=#27 id=27 data-nosnippet>27</a>
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">impl </span>SetVariables {
<a href=#29 id=29 data-nosnippet>29</a> <span class="doccomment">/// Returns the first supported `search_path` value.
<a href=#30 id=30 data-nosnippet>30</a> </span><span class="kw">pub fn </span>search_path(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>str&gt; {
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">let </span>[ObjectNamePart::Identifier(variable)] = <span class="self">self</span>.variable.<span class="number">0</span>.as_slice() <span class="kw">else </span>{
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#33 id=33 data-nosnippet>33</a> };
<a href=#34 id=34 data-nosnippet>34</a> <span class="kw">if </span>variable.quote_style.is_some() || !variable.value.eq_ignore_ascii_case(<span class="string">"search_path"</span>) {
<a href=#35 id=35 data-nosnippet>35</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#36 id=36 data-nosnippet>36</a> }
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a> <span class="kw">match </span><span class="self">self</span>.value.first()<span class="question-mark">? </span>{
<a href=#39 id=39 data-nosnippet>39</a> Expr::Value(ValueWithSpan {
<a href=#40 id=40 data-nosnippet>40</a> value: Value::SingleQuotedString(value) | Value::DoubleQuotedString(value),
<a href=#41 id=41 data-nosnippet>41</a> ..
<a href=#42 id=42 data-nosnippet>42</a> }) =&gt; <span class="prelude-val">Some</span>(value),
<a href=#43 id=43 data-nosnippet>43</a> Expr::Identifier(value) =&gt; <span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>value.value),
<a href=#44 id=44 data-nosnippet>44</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#45 id=45 data-nosnippet>45</a> }
<a href=#46 id=46 data-nosnippet>46</a> }
<a href=#47 id=47 data-nosnippet>47</a>}
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a><span class="kw">impl </span>Display <span class="kw">for </span>SetVariables {
<a href=#50 id=50 data-nosnippet>50</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">let </span>variable = <span class="kw-2">&amp;</span><span class="self">self</span>.variable;
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">let </span>value = <span class="kw-2">&amp;</span><span class="self">self
<a href=#53 id=53 data-nosnippet>53</a> </span>.value
<a href=#54 id=54 data-nosnippet>54</a> .iter()
<a href=#55 id=55 data-nosnippet>55</a> .map(|expr| <span class="macro">format!</span>(<span class="string">"{}"</span>, expr))
<a href=#56 id=56 data-nosnippet>56</a> .collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;()
<a href=#57 id=57 data-nosnippet>57</a> .join(<span class="string">", "</span>);
<a href=#58 id=58 data-nosnippet>58</a>
<a href=#59 id=59 data-nosnippet>59</a> <span class="macro">write!</span>(f, <span class="string">r#"SET {variable} = {value}"#</span>)
<a href=#60 id=60 data-nosnippet>60</a> }
<a href=#61 id=61 data-nosnippet>61</a>}
<a href=#62 id=62 data-nosnippet>62</a>
<a href=#63 id=63 data-nosnippet>63</a><span class="attr">#[cfg(test)]
<a href=#64 id=64 data-nosnippet>64</a></span><span class="kw">mod </span>tests {
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">use </span>std::assert_matches;
<a href=#66 id=66 data-nosnippet>66</a>
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#68 id=68 data-nosnippet>68</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#70 id=70 data-nosnippet>70</a>
<a href=#71 id=71 data-nosnippet>71</a> <span class="attr">#[test]
<a href=#72 id=72 data-nosnippet>72</a> </span><span class="kw">fn </span>test_display_show_variables() {
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">let </span>sql = <span class="string">r"set delayed_insert_timeout=300;"</span>;
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">let </span>stmts =
<a href=#75 id=75 data-nosnippet>75</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#76 id=76 data-nosnippet>76</a> .unwrap();
<a href=#77 id=77 data-nosnippet>77</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#78 id=78 data-nosnippet>78</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::SetVariables { .. });
<a href=#79 id=79 data-nosnippet>79</a>
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#81 id=81 data-nosnippet>81</a> Statement::SetVariables(set) =&gt; {
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, set);
<a href=#83 id=83 data-nosnippet>83</a> <span class="macro">assert_eq!</span>(
<a href=#84 id=84 data-nosnippet>84</a> <span class="string">r#"
<a href=#85 id=85 data-nosnippet>85</a>SET delayed_insert_timeout = 300"#</span>,
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw-2">&amp;</span>new_sql
<a href=#87 id=87 data-nosnippet>87</a> );
<a href=#88 id=88 data-nosnippet>88</a> }
<a href=#89 id=89 data-nosnippet>89</a> <span class="kw">_ </span>=&gt; {
<a href=#90 id=90 data-nosnippet>90</a> <span class="macro">unreachable!</span>();
<a href=#91 id=91 data-nosnippet>91</a> }
<a href=#92 id=92 data-nosnippet>92</a> }
<a href=#93 id=93 data-nosnippet>93</a> }
<a href=#94 id=94 data-nosnippet>94</a>
<a href=#95 id=95 data-nosnippet>95</a> <span class="attr">#[test]
<a href=#96 id=96 data-nosnippet>96</a> </span><span class="kw">fn </span>test_search_path() {
<a href=#97 id=97 data-nosnippet>97</a> <span class="kw">for </span>(sql, expected) <span class="kw">in </span>[
<a href=#98 id=98 data-nosnippet>98</a> (<span class="string">"SET search_path TO public"</span>, <span class="prelude-val">Some</span>(<span class="string">"public"</span>)),
<a href=#99 id=99 data-nosnippet>99</a> (<span class="string">"SET SEARCH_PATH TO 'private'"</span>, <span class="prelude-val">Some</span>(<span class="string">"private"</span>)),
<a href=#100 id=100 data-nosnippet>100</a> (<span class="string">"SET search_path TO \"quoted\""</span>, <span class="prelude-val">Some</span>(<span class="string">"quoted"</span>)),
<a href=#101 id=101 data-nosnippet>101</a> (<span class="string">"SET \"search_path\" TO private"</span>, <span class="prelude-val">None</span>),
<a href=#102 id=102 data-nosnippet>102</a> (<span class="string">"SET timezone TO 'UTC'"</span>, <span class="prelude-val">None</span>),
<a href=#103 id=103 data-nosnippet>103</a> ] {
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">let </span>statements = ParserContext::create_with_dialect(
<a href=#105 id=105 data-nosnippet>105</a> sql,
<a href=#106 id=106 data-nosnippet>106</a> <span class="kw-2">&amp;</span>GreptimeDbDialect {},
<a href=#107 id=107 data-nosnippet>107</a> ParseOptions::default(),
<a href=#108 id=108 data-nosnippet>108</a> )
<a href=#109 id=109 data-nosnippet>109</a> .unwrap();
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">let </span>[Statement::SetVariables(set)] = statements.as_slice() <span class="kw">else </span>{
<a href=#111 id=111 data-nosnippet>111</a> <span class="macro">unreachable!</span>()
<a href=#112 id=112 data-nosnippet>112</a> };
<a href=#113 id=113 data-nosnippet>113</a> <span class="macro">assert_eq!</span>(expected, set.search_path());
<a href=#114 id=114 data-nosnippet>114</a> }
<a href=#115 id=115 data-nosnippet>115</a> }
<a href=#116 id=116 data-nosnippet>116</a>}
</code></pre></div></section></main></body></html>
+730
View File
@@ -0,0 +1,730 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/show.rs`."><title>show.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>show.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::{<span class="self">self</span>, Display};
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#19 id=19 data-nosnippet>19</a>
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span><span class="kw">crate</span>::ast::{Expr, Ident, ObjectName};
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="doccomment">/// Show kind for SQL expressions like `SHOW DATABASE` or `SHOW TABLE`
<a href=#23 id=23 data-nosnippet>23</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">pub enum </span>ShowKind {
<a href=#25 id=25 data-nosnippet>25</a> All,
<a href=#26 id=26 data-nosnippet>26</a> Like(Ident),
<a href=#27 id=27 data-nosnippet>27</a> Where(Expr),
<a href=#28 id=28 data-nosnippet>28</a>}
<a href=#29 id=29 data-nosnippet>29</a>
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowKind {
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter) -&gt; fmt::Result {
<a href=#32 id=32 data-nosnippet>32</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#33 id=33 data-nosnippet>33</a> <span class="comment">// The `All` is the default kind placeholder, not a valid statement.
<a href=#34 id=34 data-nosnippet>34</a> </span>ShowKind::All =&gt; <span class="macro">write!</span>(f, <span class="string">""</span>),
<a href=#35 id=35 data-nosnippet>35</a> ShowKind::Like(ident) =&gt; <span class="macro">write!</span>(f, <span class="string">"LIKE {ident}"</span>),
<a href=#36 id=36 data-nosnippet>36</a> ShowKind::Where(expr) =&gt; <span class="macro">write!</span>(f, <span class="string">"WHERE {expr}"</span>),
<a href=#37 id=37 data-nosnippet>37</a> }
<a href=#38 id=38 data-nosnippet>38</a> }
<a href=#39 id=39 data-nosnippet>39</a>}
<a href=#40 id=40 data-nosnippet>40</a>
<a href=#41 id=41 data-nosnippet>41</a><span class="macro">macro_rules!</span> format_kind {
<a href=#42 id=42 data-nosnippet>42</a> (<span class="macro-nonterminal">$self</span>: expr, <span class="macro-nonterminal">$f</span>: expr) =&gt; {
<a href=#43 id=43 data-nosnippet>43</a> <span class="kw">if </span><span class="macro-nonterminal">$self</span>.kind != ShowKind::All {
<a href=#44 id=44 data-nosnippet>44</a> <span class="macro">write!</span>(<span class="macro-nonterminal">$f</span>, <span class="string">" {}"</span>, <span class="macro-nonterminal">$self</span>.kind)<span class="question-mark">?</span>;
<a href=#45 id=45 data-nosnippet>45</a> }
<a href=#46 id=46 data-nosnippet>46</a> };
<a href=#47 id=47 data-nosnippet>47</a>}
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#50 id=50 data-nosnippet>50</a></span><span class="kw">pub mod </span>trigger;
<a href=#51 id=51 data-nosnippet>51</a>
<a href=#52 id=52 data-nosnippet>52</a><span class="doccomment">/// SQL structure for `SHOW DATABASES`.
<a href=#53 id=53 data-nosnippet>53</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#54 id=54 data-nosnippet>54</a></span><span class="kw">pub struct </span>ShowDatabases {
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#56 id=56 data-nosnippet>56</a> <span class="kw">pub </span>full: bool,
<a href=#57 id=57 data-nosnippet>57</a>}
<a href=#58 id=58 data-nosnippet>58</a>
<a href=#59 id=59 data-nosnippet>59</a><span class="doccomment">/// The SQL `SHOW COLUMNS` statement
<a href=#60 id=60 data-nosnippet>60</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#61 id=61 data-nosnippet>61</a></span><span class="kw">pub struct </span>ShowColumns {
<a href=#62 id=62 data-nosnippet>62</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#63 id=63 data-nosnippet>63</a> <span class="kw">pub </span>table: String,
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">pub </span>full: bool,
<a href=#66 id=66 data-nosnippet>66</a>}
<a href=#67 id=67 data-nosnippet>67</a>
<a href=#68 id=68 data-nosnippet>68</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowColumns {
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#70 id=70 data-nosnippet>70</a> <span class="macro">write!</span>(f, <span class="string">"SHOW "</span>)<span class="question-mark">?</span>;
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">if </span><span class="self">self</span>.full {
<a href=#72 id=72 data-nosnippet>72</a> <span class="macro">write!</span>(f, <span class="string">"FULL "</span>)<span class="question-mark">?</span>;
<a href=#73 id=73 data-nosnippet>73</a> }
<a href=#74 id=74 data-nosnippet>74</a> <span class="macro">write!</span>(f, <span class="string">"COLUMNS IN {}"</span>, <span class="self">self</span>.table)<span class="question-mark">?</span>;
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#76 id=76 data-nosnippet>76</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#77 id=77 data-nosnippet>77</a> }
<a href=#78 id=78 data-nosnippet>78</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#79 id=79 data-nosnippet>79</a> <span class="prelude-val">Ok</span>(())
<a href=#80 id=80 data-nosnippet>80</a> }
<a href=#81 id=81 data-nosnippet>81</a>}
<a href=#82 id=82 data-nosnippet>82</a>
<a href=#83 id=83 data-nosnippet>83</a><span class="doccomment">/// The SQL `SHOW INDEX` statement
<a href=#84 id=84 data-nosnippet>84</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#85 id=85 data-nosnippet>85</a></span><span class="kw">pub struct </span>ShowIndex {
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#87 id=87 data-nosnippet>87</a> <span class="kw">pub </span>table: String,
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#89 id=89 data-nosnippet>89</a>}
<a href=#90 id=90 data-nosnippet>90</a>
<a href=#91 id=91 data-nosnippet>91</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowIndex {
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#93 id=93 data-nosnippet>93</a> <span class="macro">write!</span>(f, <span class="string">"SHOW INDEX IN {}"</span>, <span class="self">self</span>.table)<span class="question-mark">?</span>;
<a href=#94 id=94 data-nosnippet>94</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#95 id=95 data-nosnippet>95</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#96 id=96 data-nosnippet>96</a> }
<a href=#97 id=97 data-nosnippet>97</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#98 id=98 data-nosnippet>98</a>
<a href=#99 id=99 data-nosnippet>99</a> <span class="prelude-val">Ok</span>(())
<a href=#100 id=100 data-nosnippet>100</a> }
<a href=#101 id=101 data-nosnippet>101</a>}
<a href=#102 id=102 data-nosnippet>102</a>
<a href=#103 id=103 data-nosnippet>103</a><span class="doccomment">/// The SQL `SHOW REGION` statement
<a href=#104 id=104 data-nosnippet>104</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#105 id=105 data-nosnippet>105</a></span><span class="kw">pub struct </span>ShowRegion {
<a href=#106 id=106 data-nosnippet>106</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#107 id=107 data-nosnippet>107</a> <span class="kw">pub </span>table: String,
<a href=#108 id=108 data-nosnippet>108</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#109 id=109 data-nosnippet>109</a>}
<a href=#110 id=110 data-nosnippet>110</a>
<a href=#111 id=111 data-nosnippet>111</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowRegion {
<a href=#112 id=112 data-nosnippet>112</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#113 id=113 data-nosnippet>113</a> <span class="macro">write!</span>(f, <span class="string">"SHOW REGION IN {}"</span>, <span class="self">self</span>.table)<span class="question-mark">?</span>;
<a href=#114 id=114 data-nosnippet>114</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#115 id=115 data-nosnippet>115</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#118 id=118 data-nosnippet>118</a> <span class="prelude-val">Ok</span>(())
<a href=#119 id=119 data-nosnippet>119</a> }
<a href=#120 id=120 data-nosnippet>120</a>}
<a href=#121 id=121 data-nosnippet>121</a>
<a href=#122 id=122 data-nosnippet>122</a><span class="kw">impl </span>ShowDatabases {
<a href=#123 id=123 data-nosnippet>123</a> <span class="doccomment">/// Creates a statement for `SHOW DATABASES`
<a href=#124 id=124 data-nosnippet>124</a> </span><span class="kw">pub fn </span>new(kind: ShowKind, full: bool) -&gt; <span class="self">Self </span>{
<a href=#125 id=125 data-nosnippet>125</a> ShowDatabases { kind, full }
<a href=#126 id=126 data-nosnippet>126</a> }
<a href=#127 id=127 data-nosnippet>127</a>}
<a href=#128 id=128 data-nosnippet>128</a>
<a href=#129 id=129 data-nosnippet>129</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowDatabases {
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">if </span><span class="self">self</span>.full {
<a href=#132 id=132 data-nosnippet>132</a> <span class="macro">write!</span>(f, <span class="string">"SHOW FULL DATABASES"</span>)<span class="question-mark">?</span>;
<a href=#133 id=133 data-nosnippet>133</a> } <span class="kw">else </span>{
<a href=#134 id=134 data-nosnippet>134</a> <span class="macro">write!</span>(f, <span class="string">"SHOW DATABASES"</span>)<span class="question-mark">?</span>;
<a href=#135 id=135 data-nosnippet>135</a> }
<a href=#136 id=136 data-nosnippet>136</a>
<a href=#137 id=137 data-nosnippet>137</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#138 id=138 data-nosnippet>138</a>
<a href=#139 id=139 data-nosnippet>139</a> <span class="prelude-val">Ok</span>(())
<a href=#140 id=140 data-nosnippet>140</a> }
<a href=#141 id=141 data-nosnippet>141</a>}
<a href=#142 id=142 data-nosnippet>142</a>
<a href=#143 id=143 data-nosnippet>143</a><span class="doccomment">/// SQL structure for `SHOW TABLES`.
<a href=#144 id=144 data-nosnippet>144</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#145 id=145 data-nosnippet>145</a></span><span class="kw">pub struct </span>ShowTables {
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#148 id=148 data-nosnippet>148</a> <span class="kw">pub </span>full: bool,
<a href=#149 id=149 data-nosnippet>149</a>}
<a href=#150 id=150 data-nosnippet>150</a>
<a href=#151 id=151 data-nosnippet>151</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowTables {
<a href=#152 id=152 data-nosnippet>152</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#153 id=153 data-nosnippet>153</a> <span class="macro">write!</span>(f, <span class="string">"SHOW "</span>)<span class="question-mark">?</span>;
<a href=#154 id=154 data-nosnippet>154</a> <span class="kw">if </span><span class="self">self</span>.full {
<a href=#155 id=155 data-nosnippet>155</a> <span class="macro">write!</span>(f, <span class="string">"FULL "</span>)<span class="question-mark">?</span>;
<a href=#156 id=156 data-nosnippet>156</a> }
<a href=#157 id=157 data-nosnippet>157</a> <span class="macro">write!</span>(f, <span class="string">"TABLES"</span>)<span class="question-mark">?</span>;
<a href=#158 id=158 data-nosnippet>158</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#159 id=159 data-nosnippet>159</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#160 id=160 data-nosnippet>160</a> }
<a href=#161 id=161 data-nosnippet>161</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#162 id=162 data-nosnippet>162</a>
<a href=#163 id=163 data-nosnippet>163</a> <span class="prelude-val">Ok</span>(())
<a href=#164 id=164 data-nosnippet>164</a> }
<a href=#165 id=165 data-nosnippet>165</a>}
<a href=#166 id=166 data-nosnippet>166</a>
<a href=#167 id=167 data-nosnippet>167</a><span class="doccomment">/// SQL structure for `SHOW TABLE STATUS`.
<a href=#168 id=168 data-nosnippet>168</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#169 id=169 data-nosnippet>169</a></span><span class="kw">pub struct </span>ShowTableStatus {
<a href=#170 id=170 data-nosnippet>170</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#172 id=172 data-nosnippet>172</a>}
<a href=#173 id=173 data-nosnippet>173</a>
<a href=#174 id=174 data-nosnippet>174</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowTableStatus {
<a href=#175 id=175 data-nosnippet>175</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#176 id=176 data-nosnippet>176</a> <span class="macro">write!</span>(f, <span class="string">"SHOW TABLE STATUS"</span>)<span class="question-mark">?</span>;
<a href=#177 id=177 data-nosnippet>177</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#178 id=178 data-nosnippet>178</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#179 id=179 data-nosnippet>179</a> }
<a href=#180 id=180 data-nosnippet>180</a>
<a href=#181 id=181 data-nosnippet>181</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#182 id=182 data-nosnippet>182</a>
<a href=#183 id=183 data-nosnippet>183</a> <span class="prelude-val">Ok</span>(())
<a href=#184 id=184 data-nosnippet>184</a> }
<a href=#185 id=185 data-nosnippet>185</a>}
<a href=#186 id=186 data-nosnippet>186</a>
<a href=#187 id=187 data-nosnippet>187</a><span class="doccomment">/// SQL structure for `SHOW CREATE DATABASE`.
<a href=#188 id=188 data-nosnippet>188</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#189 id=189 data-nosnippet>189</a></span><span class="kw">pub struct </span>ShowCreateDatabase {
<a href=#190 id=190 data-nosnippet>190</a> <span class="kw">pub </span>database_name: ObjectName,
<a href=#191 id=191 data-nosnippet>191</a>}
<a href=#192 id=192 data-nosnippet>192</a>
<a href=#193 id=193 data-nosnippet>193</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowCreateDatabase {
<a href=#194 id=194 data-nosnippet>194</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#195 id=195 data-nosnippet>195</a> <span class="kw">let </span>database_name = <span class="kw-2">&amp;</span><span class="self">self</span>.database_name;
<a href=#196 id=196 data-nosnippet>196</a> <span class="macro">write!</span>(f, <span class="string">r#"SHOW CREATE DATABASE {database_name}"#</span>)
<a href=#197 id=197 data-nosnippet>197</a> }
<a href=#198 id=198 data-nosnippet>198</a>}
<a href=#199 id=199 data-nosnippet>199</a>
<a href=#200 id=200 data-nosnippet>200</a><span class="doccomment">/// SQL structure for `SHOW CREATE TABLE`.
<a href=#201 id=201 data-nosnippet>201</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#202 id=202 data-nosnippet>202</a></span><span class="kw">pub struct </span>ShowCreateTable {
<a href=#203 id=203 data-nosnippet>203</a> <span class="kw">pub </span>table_name: ObjectName,
<a href=#204 id=204 data-nosnippet>204</a> <span class="kw">pub </span>variant: ShowCreateTableVariant,
<a href=#205 id=205 data-nosnippet>205</a>}
<a href=#206 id=206 data-nosnippet>206</a>
<a href=#207 id=207 data-nosnippet>207</a><span class="doccomment">/// Variant of a show create table
<a href=#208 id=208 data-nosnippet>208</a></span><span class="attr">#[derive(Default, Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#209 id=209 data-nosnippet>209</a></span><span class="kw">pub enum </span>ShowCreateTableVariant {
<a href=#210 id=210 data-nosnippet>210</a> <span class="attr">#[default]
<a href=#211 id=211 data-nosnippet>211</a> </span>Original,
<a href=#212 id=212 data-nosnippet>212</a> PostgresForeignTable,
<a href=#213 id=213 data-nosnippet>213</a>}
<a href=#214 id=214 data-nosnippet>214</a>
<a href=#215 id=215 data-nosnippet>215</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowCreateTable {
<a href=#216 id=216 data-nosnippet>216</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#217 id=217 data-nosnippet>217</a> <span class="kw">let </span>table_name = <span class="kw-2">&amp;</span><span class="self">self</span>.table_name;
<a href=#218 id=218 data-nosnippet>218</a> <span class="macro">write!</span>(f, <span class="string">r#"SHOW CREATE TABLE {table_name}"#</span>)<span class="question-mark">?</span>;
<a href=#219 id=219 data-nosnippet>219</a> <span class="kw">if let </span>ShowCreateTableVariant::PostgresForeignTable = <span class="self">self</span>.variant {
<a href=#220 id=220 data-nosnippet>220</a> <span class="macro">write!</span>(f, <span class="string">" FOR POSTGRES_FOREIGN_TABLE"</span>)<span class="question-mark">?</span>;
<a href=#221 id=221 data-nosnippet>221</a> }
<a href=#222 id=222 data-nosnippet>222</a>
<a href=#223 id=223 data-nosnippet>223</a> <span class="prelude-val">Ok</span>(())
<a href=#224 id=224 data-nosnippet>224</a> }
<a href=#225 id=225 data-nosnippet>225</a>}
<a href=#226 id=226 data-nosnippet>226</a>
<a href=#227 id=227 data-nosnippet>227</a><span class="doccomment">/// SQL structure for `SHOW CREATE FLOW`.
<a href=#228 id=228 data-nosnippet>228</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#229 id=229 data-nosnippet>229</a></span><span class="kw">pub struct </span>ShowCreateFlow {
<a href=#230 id=230 data-nosnippet>230</a> <span class="kw">pub </span>flow_name: ObjectName,
<a href=#231 id=231 data-nosnippet>231</a>}
<a href=#232 id=232 data-nosnippet>232</a>
<a href=#233 id=233 data-nosnippet>233</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowCreateFlow {
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#235 id=235 data-nosnippet>235</a> <span class="kw">let </span>flow_name = <span class="kw-2">&amp;</span><span class="self">self</span>.flow_name;
<a href=#236 id=236 data-nosnippet>236</a> <span class="macro">write!</span>(f, <span class="string">"SHOW CREATE FLOW {flow_name}"</span>)
<a href=#237 id=237 data-nosnippet>237</a> }
<a href=#238 id=238 data-nosnippet>238</a>}
<a href=#239 id=239 data-nosnippet>239</a>
<a href=#240 id=240 data-nosnippet>240</a><span class="doccomment">/// SQL structure for `SHOW FLOWS`.
<a href=#241 id=241 data-nosnippet>241</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#242 id=242 data-nosnippet>242</a></span><span class="kw">pub struct </span>ShowFlows {
<a href=#243 id=243 data-nosnippet>243</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#244 id=244 data-nosnippet>244</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#245 id=245 data-nosnippet>245</a>}
<a href=#246 id=246 data-nosnippet>246</a>
<a href=#247 id=247 data-nosnippet>247</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowFlows {
<a href=#248 id=248 data-nosnippet>248</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#249 id=249 data-nosnippet>249</a> <span class="macro">write!</span>(f, <span class="string">"SHOW FLOWS"</span>)<span class="question-mark">?</span>;
<a href=#250 id=250 data-nosnippet>250</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#251 id=251 data-nosnippet>251</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#252 id=252 data-nosnippet>252</a> }
<a href=#253 id=253 data-nosnippet>253</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#254 id=254 data-nosnippet>254</a>
<a href=#255 id=255 data-nosnippet>255</a> <span class="prelude-val">Ok</span>(())
<a href=#256 id=256 data-nosnippet>256</a> }
<a href=#257 id=257 data-nosnippet>257</a>}
<a href=#258 id=258 data-nosnippet>258</a>
<a href=#259 id=259 data-nosnippet>259</a><span class="doccomment">/// SQL structure for `SHOW FLOW STATUS`.
<a href=#260 id=260 data-nosnippet>260</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#261 id=261 data-nosnippet>261</a></span><span class="kw">pub struct </span>ShowFlowStatus {
<a href=#262 id=262 data-nosnippet>262</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#263 id=263 data-nosnippet>263</a>}
<a href=#264 id=264 data-nosnippet>264</a>
<a href=#265 id=265 data-nosnippet>265</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowFlowStatus {
<a href=#266 id=266 data-nosnippet>266</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#267 id=267 data-nosnippet>267</a> <span class="macro">write!</span>(f, <span class="string">"SHOW FLOW STATUS"</span>)<span class="question-mark">?</span>;
<a href=#268 id=268 data-nosnippet>268</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#269 id=269 data-nosnippet>269</a>
<a href=#270 id=270 data-nosnippet>270</a> <span class="prelude-val">Ok</span>(())
<a href=#271 id=271 data-nosnippet>271</a> }
<a href=#272 id=272 data-nosnippet>272</a>}
<a href=#273 id=273 data-nosnippet>273</a>
<a href=#274 id=274 data-nosnippet>274</a><span class="doccomment">/// SQL structure for `SHOW CREATE VIEW`.
<a href=#275 id=275 data-nosnippet>275</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#276 id=276 data-nosnippet>276</a></span><span class="kw">pub struct </span>ShowCreateView {
<a href=#277 id=277 data-nosnippet>277</a> <span class="kw">pub </span>view_name: ObjectName,
<a href=#278 id=278 data-nosnippet>278</a>}
<a href=#279 id=279 data-nosnippet>279</a>
<a href=#280 id=280 data-nosnippet>280</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowCreateView {
<a href=#281 id=281 data-nosnippet>281</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#282 id=282 data-nosnippet>282</a> <span class="kw">let </span>view_name = <span class="kw-2">&amp;</span><span class="self">self</span>.view_name;
<a href=#283 id=283 data-nosnippet>283</a> <span class="macro">write!</span>(f, <span class="string">"SHOW CREATE VIEW {view_name}"</span>)
<a href=#284 id=284 data-nosnippet>284</a> }
<a href=#285 id=285 data-nosnippet>285</a>}
<a href=#286 id=286 data-nosnippet>286</a>
<a href=#287 id=287 data-nosnippet>287</a><span class="doccomment">/// SQL structure for `SHOW VIEWS`.
<a href=#288 id=288 data-nosnippet>288</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#289 id=289 data-nosnippet>289</a></span><span class="kw">pub struct </span>ShowViews {
<a href=#290 id=290 data-nosnippet>290</a> <span class="kw">pub </span>kind: ShowKind,
<a href=#291 id=291 data-nosnippet>291</a> <span class="kw">pub </span>database: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#292 id=292 data-nosnippet>292</a>}
<a href=#293 id=293 data-nosnippet>293</a>
<a href=#294 id=294 data-nosnippet>294</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowViews {
<a href=#295 id=295 data-nosnippet>295</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#296 id=296 data-nosnippet>296</a> <span class="macro">write!</span>(f, <span class="string">"SHOW VIEWS"</span>)<span class="question-mark">?</span>;
<a href=#297 id=297 data-nosnippet>297</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(database) = <span class="kw-2">&amp;</span><span class="self">self</span>.database {
<a href=#298 id=298 data-nosnippet>298</a> <span class="macro">write!</span>(f, <span class="string">" IN {database}"</span>)<span class="question-mark">?</span>;
<a href=#299 id=299 data-nosnippet>299</a> }
<a href=#300 id=300 data-nosnippet>300</a> <span class="macro">format_kind!</span>(<span class="self">self</span>, f);
<a href=#301 id=301 data-nosnippet>301</a>
<a href=#302 id=302 data-nosnippet>302</a> <span class="prelude-val">Ok</span>(())
<a href=#303 id=303 data-nosnippet>303</a> }
<a href=#304 id=304 data-nosnippet>304</a>}
<a href=#305 id=305 data-nosnippet>305</a>
<a href=#306 id=306 data-nosnippet>306</a><span class="doccomment">/// SQL structure for `SHOW VARIABLES xxx`.
<a href=#307 id=307 data-nosnippet>307</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#308 id=308 data-nosnippet>308</a></span><span class="kw">pub struct </span>ShowVariables {
<a href=#309 id=309 data-nosnippet>309</a> <span class="kw">pub </span>variable: ObjectName,
<a href=#310 id=310 data-nosnippet>310</a>}
<a href=#311 id=311 data-nosnippet>311</a>
<a href=#312 id=312 data-nosnippet>312</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowVariables {
<a href=#313 id=313 data-nosnippet>313</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#314 id=314 data-nosnippet>314</a> <span class="kw">let </span>variable = <span class="kw-2">&amp;</span><span class="self">self</span>.variable;
<a href=#315 id=315 data-nosnippet>315</a> <span class="macro">write!</span>(f, <span class="string">r#"SHOW VARIABLES {variable}"#</span>)
<a href=#316 id=316 data-nosnippet>316</a> }
<a href=#317 id=317 data-nosnippet>317</a>}
<a href=#318 id=318 data-nosnippet>318</a>
<a href=#319 id=319 data-nosnippet>319</a><span class="doccomment">/// SQL structure for "SHOW STATUS"
<a href=#320 id=320 data-nosnippet>320</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#321 id=321 data-nosnippet>321</a></span><span class="kw">pub struct </span>ShowStatus {}
<a href=#322 id=322 data-nosnippet>322</a>
<a href=#323 id=323 data-nosnippet>323</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowStatus {
<a href=#324 id=324 data-nosnippet>324</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#325 id=325 data-nosnippet>325</a> <span class="macro">write!</span>(f, <span class="string">"SHOW STATUS"</span>)
<a href=#326 id=326 data-nosnippet>326</a> }
<a href=#327 id=327 data-nosnippet>327</a>}
<a href=#328 id=328 data-nosnippet>328</a>
<a href=#329 id=329 data-nosnippet>329</a><span class="doccomment">/// SQL structure for "SHOW SEARCH_PATH" postgres only
<a href=#330 id=330 data-nosnippet>330</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#331 id=331 data-nosnippet>331</a></span><span class="kw">pub struct </span>ShowSearchPath {}
<a href=#332 id=332 data-nosnippet>332</a>
<a href=#333 id=333 data-nosnippet>333</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowSearchPath {
<a href=#334 id=334 data-nosnippet>334</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#335 id=335 data-nosnippet>335</a> <span class="macro">write!</span>(f, <span class="string">"SHOW SEARCH_PATH"</span>)
<a href=#336 id=336 data-nosnippet>336</a> }
<a href=#337 id=337 data-nosnippet>337</a>}
<a href=#338 id=338 data-nosnippet>338</a>
<a href=#339 id=339 data-nosnippet>339</a><span class="doccomment">/// SQL structure for `SHOW PROCESSLIST`.
<a href=#340 id=340 data-nosnippet>340</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#341 id=341 data-nosnippet>341</a></span><span class="kw">pub struct </span>ShowProcessList {
<a href=#342 id=342 data-nosnippet>342</a> <span class="kw">pub </span>full: bool,
<a href=#343 id=343 data-nosnippet>343</a>}
<a href=#344 id=344 data-nosnippet>344</a><span class="kw">impl </span>Display <span class="kw">for </span>ShowProcessList {
<a href=#345 id=345 data-nosnippet>345</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; fmt::Result {
<a href=#346 id=346 data-nosnippet>346</a> <span class="kw">if </span><span class="self">self</span>.full {
<a href=#347 id=347 data-nosnippet>347</a> <span class="macro">write!</span>(f, <span class="string">"SHOW FULL PROCESSLIST"</span>)<span class="question-mark">?</span>;
<a href=#348 id=348 data-nosnippet>348</a> } <span class="kw">else </span>{
<a href=#349 id=349 data-nosnippet>349</a> <span class="macro">write!</span>(f, <span class="string">"SHOW PROCESSLIST"</span>)<span class="question-mark">?</span>;
<a href=#350 id=350 data-nosnippet>350</a> }
<a href=#351 id=351 data-nosnippet>351</a>
<a href=#352 id=352 data-nosnippet>352</a> <span class="prelude-val">Ok</span>(())
<a href=#353 id=353 data-nosnippet>353</a> }
<a href=#354 id=354 data-nosnippet>354</a>}
<a href=#355 id=355 data-nosnippet>355</a>
<a href=#356 id=356 data-nosnippet>356</a><span class="attr">#[cfg(test)]
<a href=#357 id=357 data-nosnippet>357</a></span><span class="kw">mod </span>tests {
<a href=#358 id=358 data-nosnippet>358</a> <span class="kw">use </span>std::assert_matches;
<a href=#359 id=359 data-nosnippet>359</a>
<a href=#360 id=360 data-nosnippet>360</a> <span class="kw">use </span>sqlparser::ast::UnaryOperator;
<a href=#361 id=361 data-nosnippet>361</a>
<a href=#362 id=362 data-nosnippet>362</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#363 id=363 data-nosnippet>363</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#364 id=364 data-nosnippet>364</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#365 id=365 data-nosnippet>365</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#366 id=366 data-nosnippet>366</a>
<a href=#367 id=367 data-nosnippet>367</a> <span class="attr">#[test]
<a href=#368 id=368 data-nosnippet>368</a> </span><span class="kw">fn </span>test_kind_display() {
<a href=#369 id=369 data-nosnippet>369</a> <span class="macro">assert_eq!</span>(<span class="string">""</span>, <span class="macro">format!</span>(<span class="string">"{}"</span>, ShowKind::All));
<a href=#370 id=370 data-nosnippet>370</a> <span class="macro">assert_eq!</span>(
<a href=#371 id=371 data-nosnippet>371</a> <span class="string">"LIKE test"</span>,
<a href=#372 id=372 data-nosnippet>372</a> <span class="macro">format!</span>(<span class="string">"{}"</span>, ShowKind::Like(Ident::new(<span class="string">"test"</span>)),)
<a href=#373 id=373 data-nosnippet>373</a> );
<a href=#374 id=374 data-nosnippet>374</a> <span class="macro">assert_eq!</span>(
<a href=#375 id=375 data-nosnippet>375</a> <span class="string">"WHERE NOT a"</span>,
<a href=#376 id=376 data-nosnippet>376</a> <span class="macro">format!</span>(
<a href=#377 id=377 data-nosnippet>377</a> <span class="string">"{}"</span>,
<a href=#378 id=378 data-nosnippet>378</a> ShowKind::Where(Expr::UnaryOp {
<a href=#379 id=379 data-nosnippet>379</a> op: UnaryOperator::Not,
<a href=#380 id=380 data-nosnippet>380</a> expr: Box::new(Expr::Identifier(Ident::new(<span class="string">"a"</span>))),
<a href=#381 id=381 data-nosnippet>381</a> })
<a href=#382 id=382 data-nosnippet>382</a> )
<a href=#383 id=383 data-nosnippet>383</a> );
<a href=#384 id=384 data-nosnippet>384</a> }
<a href=#385 id=385 data-nosnippet>385</a>
<a href=#386 id=386 data-nosnippet>386</a> <span class="attr">#[test]
<a href=#387 id=387 data-nosnippet>387</a> </span><span class="kw">pub fn </span>test_show_database() {
<a href=#388 id=388 data-nosnippet>388</a> <span class="kw">let </span>sql = <span class="string">"SHOW DATABASES"</span>;
<a href=#389 id=389 data-nosnippet>389</a> <span class="kw">let </span>stmts =
<a href=#390 id=390 data-nosnippet>390</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#391 id=391 data-nosnippet>391</a> .unwrap();
<a href=#392 id=392 data-nosnippet>392</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#393 id=393 data-nosnippet>393</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowDatabases { .. });
<a href=#394 id=394 data-nosnippet>394</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#395 id=395 data-nosnippet>395</a> Statement::ShowDatabases(show) =&gt; {
<a href=#396 id=396 data-nosnippet>396</a> <span class="macro">assert_eq!</span>(ShowKind::All, show.kind);
<a href=#397 id=397 data-nosnippet>397</a> }
<a href=#398 id=398 data-nosnippet>398</a> <span class="kw">_ </span>=&gt; {
<a href=#399 id=399 data-nosnippet>399</a> <span class="macro">unreachable!</span>();
<a href=#400 id=400 data-nosnippet>400</a> }
<a href=#401 id=401 data-nosnippet>401</a> }
<a href=#402 id=402 data-nosnippet>402</a> }
<a href=#403 id=403 data-nosnippet>403</a>
<a href=#404 id=404 data-nosnippet>404</a> <span class="attr">#[test]
<a href=#405 id=405 data-nosnippet>405</a> </span><span class="kw">pub fn </span>test_show_create_table() {
<a href=#406 id=406 data-nosnippet>406</a> <span class="kw">let </span>sql = <span class="string">"SHOW CREATE TABLE test"</span>;
<a href=#407 id=407 data-nosnippet>407</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#408 id=408 data-nosnippet>408</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#409 id=409 data-nosnippet>409</a> .unwrap();
<a href=#410 id=410 data-nosnippet>410</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#411 id=411 data-nosnippet>411</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowCreateTable { .. });
<a href=#412 id=412 data-nosnippet>412</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#413 id=413 data-nosnippet>413</a> Statement::ShowCreateTable(show) =&gt; {
<a href=#414 id=414 data-nosnippet>414</a> <span class="kw">let </span>table_name = show.table_name.to_string();
<a href=#415 id=415 data-nosnippet>415</a> <span class="macro">assert_eq!</span>(table_name, <span class="string">"test"</span>);
<a href=#416 id=416 data-nosnippet>416</a> <span class="macro">assert_eq!</span>(show.variant, ShowCreateTableVariant::Original);
<a href=#417 id=417 data-nosnippet>417</a> }
<a href=#418 id=418 data-nosnippet>418</a> <span class="kw">_ </span>=&gt; {
<a href=#419 id=419 data-nosnippet>419</a> <span class="macro">unreachable!</span>();
<a href=#420 id=420 data-nosnippet>420</a> }
<a href=#421 id=421 data-nosnippet>421</a> }
<a href=#422 id=422 data-nosnippet>422</a>
<a href=#423 id=423 data-nosnippet>423</a> <span class="kw">let </span>sql = <span class="string">"SHOW CREATE TABLE test FOR POSTGRES_FOREIGN_TABLE"</span>;
<a href=#424 id=424 data-nosnippet>424</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#425 id=425 data-nosnippet>425</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#426 id=426 data-nosnippet>426</a> .unwrap();
<a href=#427 id=427 data-nosnippet>427</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#428 id=428 data-nosnippet>428</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowCreateTable { .. });
<a href=#429 id=429 data-nosnippet>429</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#430 id=430 data-nosnippet>430</a> Statement::ShowCreateTable(show) =&gt; {
<a href=#431 id=431 data-nosnippet>431</a> <span class="kw">let </span>table_name = show.table_name.to_string();
<a href=#432 id=432 data-nosnippet>432</a> <span class="macro">assert_eq!</span>(table_name, <span class="string">"test"</span>);
<a href=#433 id=433 data-nosnippet>433</a> <span class="macro">assert_eq!</span>(show.variant, ShowCreateTableVariant::PostgresForeignTable);
<a href=#434 id=434 data-nosnippet>434</a> }
<a href=#435 id=435 data-nosnippet>435</a> <span class="kw">_ </span>=&gt; {
<a href=#436 id=436 data-nosnippet>436</a> <span class="macro">unreachable!</span>();
<a href=#437 id=437 data-nosnippet>437</a> }
<a href=#438 id=438 data-nosnippet>438</a> }
<a href=#439 id=439 data-nosnippet>439</a> }
<a href=#440 id=440 data-nosnippet>440</a>
<a href=#441 id=441 data-nosnippet>441</a> <span class="attr">#[test]
<a href=#442 id=442 data-nosnippet>442</a> </span><span class="kw">pub fn </span>test_show_create_missing_table_name() {
<a href=#443 id=443 data-nosnippet>443</a> <span class="kw">let </span>sql = <span class="string">"SHOW CREATE TABLE"</span>;
<a href=#444 id=444 data-nosnippet>444</a> <span class="macro">assert!</span>(
<a href=#445 id=445 data-nosnippet>445</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#446 id=446 data-nosnippet>446</a> .is_err()
<a href=#447 id=447 data-nosnippet>447</a> );
<a href=#448 id=448 data-nosnippet>448</a> }
<a href=#449 id=449 data-nosnippet>449</a>
<a href=#450 id=450 data-nosnippet>450</a> <span class="attr">#[test]
<a href=#451 id=451 data-nosnippet>451</a> </span><span class="kw">pub fn </span>test_show_create_unknown_for() {
<a href=#452 id=452 data-nosnippet>452</a> <span class="kw">let </span>sql = <span class="string">"SHOW CREATE TABLE t FOR UNKNOWN"</span>;
<a href=#453 id=453 data-nosnippet>453</a> <span class="macro">assert!</span>(
<a href=#454 id=454 data-nosnippet>454</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#455 id=455 data-nosnippet>455</a> .is_err()
<a href=#456 id=456 data-nosnippet>456</a> );
<a href=#457 id=457 data-nosnippet>457</a> }
<a href=#458 id=458 data-nosnippet>458</a>
<a href=#459 id=459 data-nosnippet>459</a> <span class="attr">#[test]
<a href=#460 id=460 data-nosnippet>460</a> </span><span class="kw">pub fn </span>test_show_create_flow() {
<a href=#461 id=461 data-nosnippet>461</a> <span class="kw">let </span>sql = <span class="string">"SHOW CREATE FLOW test"</span>;
<a href=#462 id=462 data-nosnippet>462</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#463 id=463 data-nosnippet>463</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#464 id=464 data-nosnippet>464</a> .unwrap();
<a href=#465 id=465 data-nosnippet>465</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#466 id=466 data-nosnippet>466</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowCreateFlow { .. });
<a href=#467 id=467 data-nosnippet>467</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#468 id=468 data-nosnippet>468</a> Statement::ShowCreateFlow(show) =&gt; {
<a href=#469 id=469 data-nosnippet>469</a> <span class="kw">let </span>flow_name = show.flow_name.to_string();
<a href=#470 id=470 data-nosnippet>470</a> <span class="macro">assert_eq!</span>(flow_name, <span class="string">"test"</span>);
<a href=#471 id=471 data-nosnippet>471</a> }
<a href=#472 id=472 data-nosnippet>472</a> <span class="kw">_ </span>=&gt; {
<a href=#473 id=473 data-nosnippet>473</a> <span class="macro">unreachable!</span>();
<a href=#474 id=474 data-nosnippet>474</a> }
<a href=#475 id=475 data-nosnippet>475</a> }
<a href=#476 id=476 data-nosnippet>476</a> }
<a href=#477 id=477 data-nosnippet>477</a> <span class="attr">#[test]
<a href=#478 id=478 data-nosnippet>478</a> </span><span class="kw">pub fn </span>test_show_create_missing_flow() {
<a href=#479 id=479 data-nosnippet>479</a> <span class="kw">let </span>sql = <span class="string">"SHOW CREATE FLOW"</span>;
<a href=#480 id=480 data-nosnippet>480</a> <span class="macro">assert!</span>(
<a href=#481 id=481 data-nosnippet>481</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#482 id=482 data-nosnippet>482</a> .is_err()
<a href=#483 id=483 data-nosnippet>483</a> );
<a href=#484 id=484 data-nosnippet>484</a> }
<a href=#485 id=485 data-nosnippet>485</a>
<a href=#486 id=486 data-nosnippet>486</a> <span class="attr">#[test]
<a href=#487 id=487 data-nosnippet>487</a> </span><span class="kw">fn </span>test_display_show_variables() {
<a href=#488 id=488 data-nosnippet>488</a> <span class="kw">let </span>sql = <span class="string">r"show variables v1;"</span>;
<a href=#489 id=489 data-nosnippet>489</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#490 id=490 data-nosnippet>490</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#491 id=491 data-nosnippet>491</a> .unwrap();
<a href=#492 id=492 data-nosnippet>492</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#493 id=493 data-nosnippet>493</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowVariables { .. });
<a href=#494 id=494 data-nosnippet>494</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#495 id=495 data-nosnippet>495</a> Statement::ShowVariables(show) =&gt; {
<a href=#496 id=496 data-nosnippet>496</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#497 id=497 data-nosnippet>497</a> <span class="macro">assert_eq!</span>(
<a href=#498 id=498 data-nosnippet>498</a> <span class="string">r#"
<a href=#499 id=499 data-nosnippet>499</a>SHOW VARIABLES v1"#</span>,
<a href=#500 id=500 data-nosnippet>500</a> <span class="kw-2">&amp;</span>new_sql
<a href=#501 id=501 data-nosnippet>501</a> );
<a href=#502 id=502 data-nosnippet>502</a> }
<a href=#503 id=503 data-nosnippet>503</a> <span class="kw">_ </span>=&gt; {
<a href=#504 id=504 data-nosnippet>504</a> <span class="macro">unreachable!</span>();
<a href=#505 id=505 data-nosnippet>505</a> }
<a href=#506 id=506 data-nosnippet>506</a> }
<a href=#507 id=507 data-nosnippet>507</a> }
<a href=#508 id=508 data-nosnippet>508</a>
<a href=#509 id=509 data-nosnippet>509</a> <span class="attr">#[test]
<a href=#510 id=510 data-nosnippet>510</a> </span><span class="kw">fn </span>test_display_show_create_table() {
<a href=#511 id=511 data-nosnippet>511</a> <span class="kw">let </span>sql = <span class="string">r"show create table monitor;"</span>;
<a href=#512 id=512 data-nosnippet>512</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#513 id=513 data-nosnippet>513</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#514 id=514 data-nosnippet>514</a> .unwrap();
<a href=#515 id=515 data-nosnippet>515</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#516 id=516 data-nosnippet>516</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowCreateTable { .. });
<a href=#517 id=517 data-nosnippet>517</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#518 id=518 data-nosnippet>518</a> Statement::ShowCreateTable(show) =&gt; {
<a href=#519 id=519 data-nosnippet>519</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#520 id=520 data-nosnippet>520</a> <span class="macro">assert_eq!</span>(
<a href=#521 id=521 data-nosnippet>521</a> <span class="string">r#"
<a href=#522 id=522 data-nosnippet>522</a>SHOW CREATE TABLE monitor"#</span>,
<a href=#523 id=523 data-nosnippet>523</a> <span class="kw-2">&amp;</span>new_sql
<a href=#524 id=524 data-nosnippet>524</a> );
<a href=#525 id=525 data-nosnippet>525</a> }
<a href=#526 id=526 data-nosnippet>526</a> <span class="kw">_ </span>=&gt; {
<a href=#527 id=527 data-nosnippet>527</a> <span class="macro">unreachable!</span>();
<a href=#528 id=528 data-nosnippet>528</a> }
<a href=#529 id=529 data-nosnippet>529</a> }
<a href=#530 id=530 data-nosnippet>530</a> }
<a href=#531 id=531 data-nosnippet>531</a>
<a href=#532 id=532 data-nosnippet>532</a> <span class="attr">#[test]
<a href=#533 id=533 data-nosnippet>533</a> </span><span class="kw">fn </span>test_display_show_index() {
<a href=#534 id=534 data-nosnippet>534</a> <span class="kw">let </span>sql = <span class="string">r"show index from t1 from d1;"</span>;
<a href=#535 id=535 data-nosnippet>535</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#536 id=536 data-nosnippet>536</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#537 id=537 data-nosnippet>537</a> .unwrap();
<a href=#538 id=538 data-nosnippet>538</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#539 id=539 data-nosnippet>539</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowIndex { .. });
<a href=#540 id=540 data-nosnippet>540</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#541 id=541 data-nosnippet>541</a> Statement::ShowIndex(show) =&gt; {
<a href=#542 id=542 data-nosnippet>542</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#543 id=543 data-nosnippet>543</a> <span class="macro">assert_eq!</span>(
<a href=#544 id=544 data-nosnippet>544</a> <span class="string">r#"
<a href=#545 id=545 data-nosnippet>545</a>SHOW INDEX IN t1 IN d1"#</span>,
<a href=#546 id=546 data-nosnippet>546</a> <span class="kw-2">&amp;</span>new_sql
<a href=#547 id=547 data-nosnippet>547</a> );
<a href=#548 id=548 data-nosnippet>548</a> }
<a href=#549 id=549 data-nosnippet>549</a> <span class="kw">_ </span>=&gt; {
<a href=#550 id=550 data-nosnippet>550</a> <span class="macro">unreachable!</span>();
<a href=#551 id=551 data-nosnippet>551</a> }
<a href=#552 id=552 data-nosnippet>552</a> }
<a href=#553 id=553 data-nosnippet>553</a> }
<a href=#554 id=554 data-nosnippet>554</a>
<a href=#555 id=555 data-nosnippet>555</a> <span class="attr">#[test]
<a href=#556 id=556 data-nosnippet>556</a> </span><span class="kw">fn </span>test_display_show_columns() {
<a href=#557 id=557 data-nosnippet>557</a> <span class="kw">let </span>sql = <span class="string">r"show full columns in t1 in d1;"</span>;
<a href=#558 id=558 data-nosnippet>558</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#559 id=559 data-nosnippet>559</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#560 id=560 data-nosnippet>560</a> .unwrap();
<a href=#561 id=561 data-nosnippet>561</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#562 id=562 data-nosnippet>562</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowColumns { .. });
<a href=#563 id=563 data-nosnippet>563</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#564 id=564 data-nosnippet>564</a> Statement::ShowColumns(show) =&gt; {
<a href=#565 id=565 data-nosnippet>565</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#566 id=566 data-nosnippet>566</a> <span class="macro">assert_eq!</span>(
<a href=#567 id=567 data-nosnippet>567</a> <span class="string">r#"
<a href=#568 id=568 data-nosnippet>568</a>SHOW FULL COLUMNS IN t1 IN d1"#</span>,
<a href=#569 id=569 data-nosnippet>569</a> <span class="kw-2">&amp;</span>new_sql
<a href=#570 id=570 data-nosnippet>570</a> );
<a href=#571 id=571 data-nosnippet>571</a> }
<a href=#572 id=572 data-nosnippet>572</a> <span class="kw">_ </span>=&gt; {
<a href=#573 id=573 data-nosnippet>573</a> <span class="macro">unreachable!</span>();
<a href=#574 id=574 data-nosnippet>574</a> }
<a href=#575 id=575 data-nosnippet>575</a> }
<a href=#576 id=576 data-nosnippet>576</a> }
<a href=#577 id=577 data-nosnippet>577</a>
<a href=#578 id=578 data-nosnippet>578</a> <span class="attr">#[test]
<a href=#579 id=579 data-nosnippet>579</a> </span><span class="kw">fn </span>test_display_show_tables() {
<a href=#580 id=580 data-nosnippet>580</a> <span class="kw">let </span>sql = <span class="string">r"show full tables in d1;"</span>;
<a href=#581 id=581 data-nosnippet>581</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#582 id=582 data-nosnippet>582</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#583 id=583 data-nosnippet>583</a> .unwrap();
<a href=#584 id=584 data-nosnippet>584</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#585 id=585 data-nosnippet>585</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowTables { .. });
<a href=#586 id=586 data-nosnippet>586</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#587 id=587 data-nosnippet>587</a> Statement::ShowTables(show) =&gt; {
<a href=#588 id=588 data-nosnippet>588</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#589 id=589 data-nosnippet>589</a> <span class="macro">assert_eq!</span>(
<a href=#590 id=590 data-nosnippet>590</a> <span class="string">r#"
<a href=#591 id=591 data-nosnippet>591</a>SHOW FULL TABLES IN d1"#</span>,
<a href=#592 id=592 data-nosnippet>592</a> <span class="kw-2">&amp;</span>new_sql
<a href=#593 id=593 data-nosnippet>593</a> );
<a href=#594 id=594 data-nosnippet>594</a> }
<a href=#595 id=595 data-nosnippet>595</a> <span class="kw">_ </span>=&gt; {
<a href=#596 id=596 data-nosnippet>596</a> <span class="macro">unreachable!</span>();
<a href=#597 id=597 data-nosnippet>597</a> }
<a href=#598 id=598 data-nosnippet>598</a> }
<a href=#599 id=599 data-nosnippet>599</a>
<a href=#600 id=600 data-nosnippet>600</a> <span class="kw">let </span>sql = <span class="string">r"show full tables;"</span>;
<a href=#601 id=601 data-nosnippet>601</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#602 id=602 data-nosnippet>602</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#603 id=603 data-nosnippet>603</a> .unwrap();
<a href=#604 id=604 data-nosnippet>604</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#605 id=605 data-nosnippet>605</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowTables { .. });
<a href=#606 id=606 data-nosnippet>606</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#607 id=607 data-nosnippet>607</a> Statement::ShowTables(show) =&gt; {
<a href=#608 id=608 data-nosnippet>608</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#609 id=609 data-nosnippet>609</a> <span class="macro">assert_eq!</span>(
<a href=#610 id=610 data-nosnippet>610</a> <span class="string">r#"
<a href=#611 id=611 data-nosnippet>611</a>SHOW FULL TABLES"#</span>,
<a href=#612 id=612 data-nosnippet>612</a> <span class="kw-2">&amp;</span>new_sql
<a href=#613 id=613 data-nosnippet>613</a> );
<a href=#614 id=614 data-nosnippet>614</a> }
<a href=#615 id=615 data-nosnippet>615</a> <span class="kw">_ </span>=&gt; {
<a href=#616 id=616 data-nosnippet>616</a> <span class="macro">unreachable!</span>();
<a href=#617 id=617 data-nosnippet>617</a> }
<a href=#618 id=618 data-nosnippet>618</a> }
<a href=#619 id=619 data-nosnippet>619</a> }
<a href=#620 id=620 data-nosnippet>620</a>
<a href=#621 id=621 data-nosnippet>621</a> <span class="attr">#[test]
<a href=#622 id=622 data-nosnippet>622</a> </span><span class="kw">fn </span>test_display_show_views() {
<a href=#623 id=623 data-nosnippet>623</a> <span class="kw">let </span>sql = <span class="string">r"show views in d1;"</span>;
<a href=#624 id=624 data-nosnippet>624</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#625 id=625 data-nosnippet>625</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#626 id=626 data-nosnippet>626</a> .unwrap();
<a href=#627 id=627 data-nosnippet>627</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#628 id=628 data-nosnippet>628</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowViews { .. });
<a href=#629 id=629 data-nosnippet>629</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#630 id=630 data-nosnippet>630</a> Statement::ShowViews(show) =&gt; {
<a href=#631 id=631 data-nosnippet>631</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#632 id=632 data-nosnippet>632</a> <span class="macro">assert_eq!</span>(
<a href=#633 id=633 data-nosnippet>633</a> <span class="string">r#"
<a href=#634 id=634 data-nosnippet>634</a>SHOW VIEWS IN d1"#</span>,
<a href=#635 id=635 data-nosnippet>635</a> <span class="kw-2">&amp;</span>new_sql
<a href=#636 id=636 data-nosnippet>636</a> );
<a href=#637 id=637 data-nosnippet>637</a> }
<a href=#638 id=638 data-nosnippet>638</a> <span class="kw">_ </span>=&gt; {
<a href=#639 id=639 data-nosnippet>639</a> <span class="macro">unreachable!</span>();
<a href=#640 id=640 data-nosnippet>640</a> }
<a href=#641 id=641 data-nosnippet>641</a> }
<a href=#642 id=642 data-nosnippet>642</a>
<a href=#643 id=643 data-nosnippet>643</a> <span class="kw">let </span>sql = <span class="string">r"show views;"</span>;
<a href=#644 id=644 data-nosnippet>644</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#645 id=645 data-nosnippet>645</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#646 id=646 data-nosnippet>646</a> .unwrap();
<a href=#647 id=647 data-nosnippet>647</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#648 id=648 data-nosnippet>648</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowViews { .. });
<a href=#649 id=649 data-nosnippet>649</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#650 id=650 data-nosnippet>650</a> Statement::ShowViews(show) =&gt; {
<a href=#651 id=651 data-nosnippet>651</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#652 id=652 data-nosnippet>652</a> <span class="macro">assert_eq!</span>(
<a href=#653 id=653 data-nosnippet>653</a> <span class="string">r#"
<a href=#654 id=654 data-nosnippet>654</a>SHOW VIEWS"#</span>,
<a href=#655 id=655 data-nosnippet>655</a> <span class="kw-2">&amp;</span>new_sql
<a href=#656 id=656 data-nosnippet>656</a> );
<a href=#657 id=657 data-nosnippet>657</a> }
<a href=#658 id=658 data-nosnippet>658</a> <span class="kw">_ </span>=&gt; {
<a href=#659 id=659 data-nosnippet>659</a> <span class="macro">unreachable!</span>();
<a href=#660 id=660 data-nosnippet>660</a> }
<a href=#661 id=661 data-nosnippet>661</a> }
<a href=#662 id=662 data-nosnippet>662</a> }
<a href=#663 id=663 data-nosnippet>663</a>
<a href=#664 id=664 data-nosnippet>664</a> <span class="attr">#[test]
<a href=#665 id=665 data-nosnippet>665</a> </span><span class="kw">fn </span>test_display_show_flows() {
<a href=#666 id=666 data-nosnippet>666</a> <span class="kw">let </span>sql = <span class="string">r"show flows in d1;"</span>;
<a href=#667 id=667 data-nosnippet>667</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#668 id=668 data-nosnippet>668</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#669 id=669 data-nosnippet>669</a> .unwrap();
<a href=#670 id=670 data-nosnippet>670</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#671 id=671 data-nosnippet>671</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowFlows { .. });
<a href=#672 id=672 data-nosnippet>672</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#673 id=673 data-nosnippet>673</a> Statement::ShowFlows(show) =&gt; {
<a href=#674 id=674 data-nosnippet>674</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#675 id=675 data-nosnippet>675</a> <span class="macro">assert_eq!</span>(
<a href=#676 id=676 data-nosnippet>676</a> <span class="string">r#"
<a href=#677 id=677 data-nosnippet>677</a>SHOW FLOWS IN d1"#</span>,
<a href=#678 id=678 data-nosnippet>678</a> <span class="kw-2">&amp;</span>new_sql
<a href=#679 id=679 data-nosnippet>679</a> );
<a href=#680 id=680 data-nosnippet>680</a> }
<a href=#681 id=681 data-nosnippet>681</a> <span class="kw">_ </span>=&gt; {
<a href=#682 id=682 data-nosnippet>682</a> <span class="macro">unreachable!</span>();
<a href=#683 id=683 data-nosnippet>683</a> }
<a href=#684 id=684 data-nosnippet>684</a> }
<a href=#685 id=685 data-nosnippet>685</a>
<a href=#686 id=686 data-nosnippet>686</a> <span class="kw">let </span>sql = <span class="string">r"show flows;"</span>;
<a href=#687 id=687 data-nosnippet>687</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#688 id=688 data-nosnippet>688</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#689 id=689 data-nosnippet>689</a> .unwrap();
<a href=#690 id=690 data-nosnippet>690</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#691 id=691 data-nosnippet>691</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowFlows { .. });
<a href=#692 id=692 data-nosnippet>692</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#693 id=693 data-nosnippet>693</a> Statement::ShowFlows(show) =&gt; {
<a href=#694 id=694 data-nosnippet>694</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#695 id=695 data-nosnippet>695</a> <span class="macro">assert_eq!</span>(
<a href=#696 id=696 data-nosnippet>696</a> <span class="string">r#"
<a href=#697 id=697 data-nosnippet>697</a>SHOW FLOWS"#</span>,
<a href=#698 id=698 data-nosnippet>698</a> <span class="kw-2">&amp;</span>new_sql
<a href=#699 id=699 data-nosnippet>699</a> );
<a href=#700 id=700 data-nosnippet>700</a> }
<a href=#701 id=701 data-nosnippet>701</a> <span class="kw">_ </span>=&gt; {
<a href=#702 id=702 data-nosnippet>702</a> <span class="macro">unreachable!</span>(<span class="string">"{:?}"</span>, <span class="kw-2">&amp;</span>stmts[<span class="number">0</span>]);
<a href=#703 id=703 data-nosnippet>703</a> }
<a href=#704 id=704 data-nosnippet>704</a> }
<a href=#705 id=705 data-nosnippet>705</a> }
<a href=#706 id=706 data-nosnippet>706</a>
<a href=#707 id=707 data-nosnippet>707</a> <span class="attr">#[test]
<a href=#708 id=708 data-nosnippet>708</a> </span><span class="kw">fn </span>test_display_show_databases() {
<a href=#709 id=709 data-nosnippet>709</a> <span class="kw">let </span>sql = <span class="string">r"show databases;"</span>;
<a href=#710 id=710 data-nosnippet>710</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#711 id=711 data-nosnippet>711</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#712 id=712 data-nosnippet>712</a> .unwrap();
<a href=#713 id=713 data-nosnippet>713</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#714 id=714 data-nosnippet>714</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::ShowDatabases { .. });
<a href=#715 id=715 data-nosnippet>715</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#716 id=716 data-nosnippet>716</a> Statement::ShowDatabases(show) =&gt; {
<a href=#717 id=717 data-nosnippet>717</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, show);
<a href=#718 id=718 data-nosnippet>718</a> <span class="macro">assert_eq!</span>(
<a href=#719 id=719 data-nosnippet>719</a> <span class="string">r#"
<a href=#720 id=720 data-nosnippet>720</a>SHOW DATABASES"#</span>,
<a href=#721 id=721 data-nosnippet>721</a> <span class="kw-2">&amp;</span>new_sql
<a href=#722 id=722 data-nosnippet>722</a> );
<a href=#723 id=723 data-nosnippet>723</a> }
<a href=#724 id=724 data-nosnippet>724</a> <span class="kw">_ </span>=&gt; {
<a href=#725 id=725 data-nosnippet>725</a> <span class="macro">unreachable!</span>();
<a href=#726 id=726 data-nosnippet>726</a> }
<a href=#727 id=727 data-nosnippet>727</a> }
<a href=#728 id=728 data-nosnippet>728</a> }
<a href=#729 id=729 data-nosnippet>729</a>}
</code></pre></div></section></main></body></html>
+336
View File
@@ -0,0 +1,336 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/statement.rs`."><title>statement.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>statement.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>datafusion_sql::parser::Statement <span class="kw">as </span>DfStatement;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>serde::Serialize;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser::ast::Statement <span class="kw">as </span>SpStatement;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#21 id=21 data-nosnippet>21</a>
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span><span class="kw">crate</span>::error::{ConvertToDfStatementSnafu, Error};
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::statements::admin::Admin;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span><span class="kw">crate</span>::statements::alter::{AlterDatabase, AlterTable};
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::statements::comment::Comment;
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span><span class="kw">crate</span>::statements::copy::Copy;
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span><span class="kw">crate</span>::statements::create::{
<a href=#28 id=28 data-nosnippet>28</a> CreateDatabase, CreateExternalTable, CreateFlow, CreateTable, CreateTableLike, CreateView,
<a href=#29 id=29 data-nosnippet>29</a>};
<a href=#30 id=30 data-nosnippet>30</a><span class="kw">use </span><span class="kw">crate</span>::statements::cursor::{CloseCursor, DeclareCursor, FetchCursor};
<a href=#31 id=31 data-nosnippet>31</a><span class="kw">use </span><span class="kw">crate</span>::statements::delete::Delete;
<a href=#32 id=32 data-nosnippet>32</a><span class="kw">use </span><span class="kw">crate</span>::statements::describe::DescribeTable;
<a href=#33 id=33 data-nosnippet>33</a><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#34 id=34 data-nosnippet>34</a></span><span class="kw">use </span><span class="kw">crate</span>::statements::drop::UndropTable;
<a href=#35 id=35 data-nosnippet>35</a><span class="kw">use </span><span class="kw">crate</span>::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
<a href=#36 id=36 data-nosnippet>36</a><span class="kw">use </span><span class="kw">crate</span>::statements::explain::ExplainStatement;
<a href=#37 id=37 data-nosnippet>37</a><span class="kw">use </span><span class="kw">crate</span>::statements::insert::Insert;
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">use </span><span class="kw">crate</span>::statements::kill::Kill;
<a href=#39 id=39 data-nosnippet>39</a><span class="kw">use </span><span class="kw">crate</span>::statements::query::Query;
<a href=#40 id=40 data-nosnippet>40</a><span class="kw">use </span><span class="kw">crate</span>::statements::set_variables::SetVariables;
<a href=#41 id=41 data-nosnippet>41</a><span class="kw">use </span><span class="kw">crate</span>::statements::show::{
<a href=#42 id=42 data-nosnippet>42</a> ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
<a href=#43 id=43 data-nosnippet>43</a> ShowDatabases, ShowFlowStatus, ShowFlows, ShowIndex, ShowKind, ShowProcessList, ShowRegion,
<a href=#44 id=44 data-nosnippet>44</a> ShowSearchPath, ShowStatus, ShowTableStatus, ShowTables, ShowVariables, ShowViews,
<a href=#45 id=45 data-nosnippet>45</a>};
<a href=#46 id=46 data-nosnippet>46</a><span class="kw">use </span><span class="kw">crate</span>::statements::tql::Tql;
<a href=#47 id=47 data-nosnippet>47</a><span class="kw">use </span><span class="kw">crate</span>::statements::truncate::TruncateTable;
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a><span class="doccomment">/// Tokens parsed by `DFParser` are converted into these values.
<a href=#50 id=50 data-nosnippet>50</a></span><span class="attr">#[allow(clippy::large_enum_variant)]
<a href=#51 id=51 data-nosnippet>51</a>#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#52 id=52 data-nosnippet>52</a></span><span class="kw">pub enum </span>Statement {
<a href=#53 id=53 data-nosnippet>53</a> <span class="comment">// Query
<a href=#54 id=54 data-nosnippet>54</a> </span>Query(Box&lt;Query&gt;),
<a href=#55 id=55 data-nosnippet>55</a> <span class="comment">// Insert
<a href=#56 id=56 data-nosnippet>56</a> </span>Insert(Box&lt;Insert&gt;),
<a href=#57 id=57 data-nosnippet>57</a> <span class="comment">// Delete
<a href=#58 id=58 data-nosnippet>58</a> </span>Delete(Box&lt;Delete&gt;),
<a href=#59 id=59 data-nosnippet>59</a> <span class="doccomment">/// CREATE TABLE
<a href=#60 id=60 data-nosnippet>60</a> </span>CreateTable(CreateTable),
<a href=#61 id=61 data-nosnippet>61</a> <span class="comment">// CREATE EXTERNAL TABLE
<a href=#62 id=62 data-nosnippet>62</a> </span>CreateExternalTable(CreateExternalTable),
<a href=#63 id=63 data-nosnippet>63</a> <span class="comment">// CREATE TABLE ... LIKE
<a href=#64 id=64 data-nosnippet>64</a> </span>CreateTableLike(CreateTableLike),
<a href=#65 id=65 data-nosnippet>65</a> <span class="comment">// CREATE FLOW
<a href=#66 id=66 data-nosnippet>66</a> </span>CreateFlow(CreateFlow),
<a href=#67 id=67 data-nosnippet>67</a> <span class="comment">// CREATE VIEW ... AS
<a href=#68 id=68 data-nosnippet>68</a> </span>CreateView(CreateView),
<a href=#69 id=69 data-nosnippet>69</a> <span class="comment">// CREATE TRIGGER
<a href=#70 id=70 data-nosnippet>70</a> </span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#71 id=71 data-nosnippet>71</a> </span>CreateTrigger(<span class="kw">crate</span>::statements::create::trigger::CreateTrigger),
<a href=#72 id=72 data-nosnippet>72</a> <span class="comment">// DROP TABLE
<a href=#73 id=73 data-nosnippet>73</a> </span>DropTable(DropTable),
<a href=#74 id=74 data-nosnippet>74</a> <span class="comment">// UNDROP TABLE
<a href=#75 id=75 data-nosnippet>75</a> </span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#76 id=76 data-nosnippet>76</a> </span>UndropTable(UndropTable),
<a href=#77 id=77 data-nosnippet>77</a> <span class="comment">// DROP DATABASE
<a href=#78 id=78 data-nosnippet>78</a> </span>DropDatabase(DropDatabase),
<a href=#79 id=79 data-nosnippet>79</a> <span class="comment">// DROP FLOW
<a href=#80 id=80 data-nosnippet>80</a> </span>DropFlow(DropFlow),
<a href=#81 id=81 data-nosnippet>81</a> <span class="comment">// DROP Trigger
<a href=#82 id=82 data-nosnippet>82</a> </span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#83 id=83 data-nosnippet>83</a> </span>DropTrigger(<span class="kw">crate</span>::statements::drop::trigger::DropTrigger),
<a href=#84 id=84 data-nosnippet>84</a> <span class="comment">// DROP View
<a href=#85 id=85 data-nosnippet>85</a> </span>DropView(DropView),
<a href=#86 id=86 data-nosnippet>86</a> <span class="comment">// CREATE DATABASE
<a href=#87 id=87 data-nosnippet>87</a> </span>CreateDatabase(CreateDatabase),
<a href=#88 id=88 data-nosnippet>88</a> <span class="doccomment">/// ALTER TABLE
<a href=#89 id=89 data-nosnippet>89</a> </span>AlterTable(AlterTable),
<a href=#90 id=90 data-nosnippet>90</a> <span class="doccomment">/// ALTER DATABASE
<a href=#91 id=91 data-nosnippet>91</a> </span>AlterDatabase(AlterDatabase),
<a href=#92 id=92 data-nosnippet>92</a> <span class="doccomment">/// ALTER TRIGGER
<a href=#93 id=93 data-nosnippet>93</a> </span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#94 id=94 data-nosnippet>94</a> </span>AlterTrigger(<span class="kw">crate</span>::statements::alter::trigger::AlterTrigger),
<a href=#95 id=95 data-nosnippet>95</a> <span class="comment">// Databases.
<a href=#96 id=96 data-nosnippet>96</a> </span>ShowDatabases(ShowDatabases),
<a href=#97 id=97 data-nosnippet>97</a> <span class="comment">// SHOW TABLES
<a href=#98 id=98 data-nosnippet>98</a> </span>ShowTables(ShowTables),
<a href=#99 id=99 data-nosnippet>99</a> <span class="comment">// SHOW TABLE STATUS
<a href=#100 id=100 data-nosnippet>100</a> </span>ShowTableStatus(ShowTableStatus),
<a href=#101 id=101 data-nosnippet>101</a> <span class="comment">// SHOW COLUMNS
<a href=#102 id=102 data-nosnippet>102</a> </span>ShowColumns(ShowColumns),
<a href=#103 id=103 data-nosnippet>103</a> <span class="comment">// SHOW CHARSET or SHOW CHARACTER SET
<a href=#104 id=104 data-nosnippet>104</a> </span>ShowCharset(ShowKind),
<a href=#105 id=105 data-nosnippet>105</a> <span class="comment">// SHOW COLLATION
<a href=#106 id=106 data-nosnippet>106</a> </span>ShowCollation(ShowKind),
<a href=#107 id=107 data-nosnippet>107</a> <span class="comment">// SHOW INDEX
<a href=#108 id=108 data-nosnippet>108</a> </span>ShowIndex(ShowIndex),
<a href=#109 id=109 data-nosnippet>109</a> <span class="comment">// SHOW REGION
<a href=#110 id=110 data-nosnippet>110</a> </span>ShowRegion(ShowRegion),
<a href=#111 id=111 data-nosnippet>111</a> <span class="comment">// SHOW CREATE DATABASE
<a href=#112 id=112 data-nosnippet>112</a> </span>ShowCreateDatabase(ShowCreateDatabase),
<a href=#113 id=113 data-nosnippet>113</a> <span class="comment">// SHOW CREATE TABLE
<a href=#114 id=114 data-nosnippet>114</a> </span>ShowCreateTable(ShowCreateTable),
<a href=#115 id=115 data-nosnippet>115</a> <span class="comment">// SHOW CREATE FLOW
<a href=#116 id=116 data-nosnippet>116</a> </span>ShowCreateFlow(ShowCreateFlow),
<a href=#117 id=117 data-nosnippet>117</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#118 id=118 data-nosnippet>118</a> </span>ShowCreateTrigger(<span class="kw">crate</span>::statements::show::trigger::ShowCreateTrigger),
<a href=#119 id=119 data-nosnippet>119</a> <span class="doccomment">/// SHOW FLOWS
<a href=#120 id=120 data-nosnippet>120</a> </span>ShowFlows(ShowFlows),
<a href=#121 id=121 data-nosnippet>121</a> <span class="doccomment">/// SHOW FLOW STATUS
<a href=#122 id=122 data-nosnippet>122</a> </span>ShowFlowStatus(ShowFlowStatus),
<a href=#123 id=123 data-nosnippet>123</a> <span class="comment">// SHOW TRIGGERS
<a href=#124 id=124 data-nosnippet>124</a> </span><span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#125 id=125 data-nosnippet>125</a> </span>ShowTriggers(<span class="kw">crate</span>::statements::show::trigger::ShowTriggers),
<a href=#126 id=126 data-nosnippet>126</a> <span class="comment">// SHOW CREATE VIEW
<a href=#127 id=127 data-nosnippet>127</a> </span>ShowCreateView(ShowCreateView),
<a href=#128 id=128 data-nosnippet>128</a> <span class="comment">// SHOW STATUS
<a href=#129 id=129 data-nosnippet>129</a> </span>ShowStatus(ShowStatus),
<a href=#130 id=130 data-nosnippet>130</a> <span class="comment">// SHOW SEARCH_PATH
<a href=#131 id=131 data-nosnippet>131</a> </span>ShowSearchPath(ShowSearchPath),
<a href=#132 id=132 data-nosnippet>132</a> <span class="comment">// SHOW VIEWS
<a href=#133 id=133 data-nosnippet>133</a> </span>ShowViews(ShowViews),
<a href=#134 id=134 data-nosnippet>134</a> <span class="comment">// DESCRIBE TABLE
<a href=#135 id=135 data-nosnippet>135</a> </span>DescribeTable(DescribeTable),
<a href=#136 id=136 data-nosnippet>136</a> <span class="comment">// EXPLAIN QUERY
<a href=#137 id=137 data-nosnippet>137</a> </span>Explain(Box&lt;ExplainStatement&gt;),
<a href=#138 id=138 data-nosnippet>138</a> <span class="comment">// COPY
<a href=#139 id=139 data-nosnippet>139</a> </span>Copy(Copy),
<a href=#140 id=140 data-nosnippet>140</a> <span class="comment">// Telemetry Query Language
<a href=#141 id=141 data-nosnippet>141</a> </span>Tql(Tql),
<a href=#142 id=142 data-nosnippet>142</a> <span class="comment">// TRUNCATE TABLE
<a href=#143 id=143 data-nosnippet>143</a> </span>TruncateTable(TruncateTable),
<a href=#144 id=144 data-nosnippet>144</a> <span class="comment">// SET VARIABLES
<a href=#145 id=145 data-nosnippet>145</a> </span>SetVariables(SetVariables),
<a href=#146 id=146 data-nosnippet>146</a> <span class="comment">// SHOW VARIABLES
<a href=#147 id=147 data-nosnippet>147</a> </span>ShowVariables(ShowVariables),
<a href=#148 id=148 data-nosnippet>148</a> <span class="comment">// COMMENT ON
<a href=#149 id=149 data-nosnippet>149</a> </span>Comment(Comment),
<a href=#150 id=150 data-nosnippet>150</a> <span class="comment">// USE
<a href=#151 id=151 data-nosnippet>151</a> </span>Use(String),
<a href=#152 id=152 data-nosnippet>152</a> <span class="comment">// Admin statement(extension)
<a href=#153 id=153 data-nosnippet>153</a> </span>Admin(Admin),
<a href=#154 id=154 data-nosnippet>154</a> <span class="comment">// DECLARE ... CURSOR FOR ...
<a href=#155 id=155 data-nosnippet>155</a> </span>DeclareCursor(DeclareCursor),
<a href=#156 id=156 data-nosnippet>156</a> <span class="comment">// FETCH ... FROM ...
<a href=#157 id=157 data-nosnippet>157</a> </span>FetchCursor(FetchCursor),
<a href=#158 id=158 data-nosnippet>158</a> <span class="comment">// CLOSE
<a href=#159 id=159 data-nosnippet>159</a> </span>CloseCursor(CloseCursor),
<a href=#160 id=160 data-nosnippet>160</a> <span class="comment">// KILL &lt;process&gt;
<a href=#161 id=161 data-nosnippet>161</a> </span>Kill(Kill),
<a href=#162 id=162 data-nosnippet>162</a> <span class="comment">// SHOW PROCESSLIST
<a href=#163 id=163 data-nosnippet>163</a> </span>ShowProcesslist(ShowProcessList),
<a href=#164 id=164 data-nosnippet>164</a>}
<a href=#165 id=165 data-nosnippet>165</a>
<a href=#166 id=166 data-nosnippet>166</a><span class="kw">impl </span>Statement {
<a href=#167 id=167 data-nosnippet>167</a> <span class="kw">pub fn </span>is_readonly(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#168 id=168 data-nosnippet>168</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#169 id=169 data-nosnippet>169</a> <span class="comment">// Read-only operations
<a href=#170 id=170 data-nosnippet>170</a> </span>Statement::Query(<span class="kw">_</span>)
<a href=#171 id=171 data-nosnippet>171</a> | Statement::ShowDatabases(<span class="kw">_</span>)
<a href=#172 id=172 data-nosnippet>172</a> | Statement::ShowTables(<span class="kw">_</span>)
<a href=#173 id=173 data-nosnippet>173</a> | Statement::ShowTableStatus(<span class="kw">_</span>)
<a href=#174 id=174 data-nosnippet>174</a> | Statement::ShowColumns(<span class="kw">_</span>)
<a href=#175 id=175 data-nosnippet>175</a> | Statement::ShowCharset(<span class="kw">_</span>)
<a href=#176 id=176 data-nosnippet>176</a> | Statement::ShowCollation(<span class="kw">_</span>)
<a href=#177 id=177 data-nosnippet>177</a> | Statement::ShowIndex(<span class="kw">_</span>)
<a href=#178 id=178 data-nosnippet>178</a> | Statement::ShowRegion(<span class="kw">_</span>)
<a href=#179 id=179 data-nosnippet>179</a> | Statement::ShowCreateDatabase(<span class="kw">_</span>)
<a href=#180 id=180 data-nosnippet>180</a> | Statement::ShowCreateTable(<span class="kw">_</span>)
<a href=#181 id=181 data-nosnippet>181</a> | Statement::ShowCreateFlow(<span class="kw">_</span>)
<a href=#182 id=182 data-nosnippet>182</a> | Statement::ShowFlows(<span class="kw">_</span>)
<a href=#183 id=183 data-nosnippet>183</a> | Statement::ShowFlowStatus(<span class="kw">_</span>)
<a href=#184 id=184 data-nosnippet>184</a> | Statement::ShowCreateView(<span class="kw">_</span>)
<a href=#185 id=185 data-nosnippet>185</a> | Statement::ShowStatus(<span class="kw">_</span>)
<a href=#186 id=186 data-nosnippet>186</a> | Statement::ShowSearchPath(<span class="kw">_</span>)
<a href=#187 id=187 data-nosnippet>187</a> | Statement::ShowViews(<span class="kw">_</span>)
<a href=#188 id=188 data-nosnippet>188</a> | Statement::DescribeTable(<span class="kw">_</span>)
<a href=#189 id=189 data-nosnippet>189</a> | Statement::ShowVariables(<span class="kw">_</span>)
<a href=#190 id=190 data-nosnippet>190</a> | Statement::ShowProcesslist(<span class="kw">_</span>)
<a href=#191 id=191 data-nosnippet>191</a> | Statement::FetchCursor(<span class="kw">_</span>)
<a href=#192 id=192 data-nosnippet>192</a> | Statement::Tql(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<a href=#193 id=193 data-nosnippet>193</a>
<a href=#194 id=194 data-nosnippet>194</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#195 id=195 data-nosnippet>195</a> </span>Statement::ShowCreateTrigger(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<a href=#196 id=196 data-nosnippet>196</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#197 id=197 data-nosnippet>197</a> </span>Statement::ShowTriggers(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<a href=#198 id=198 data-nosnippet>198</a>
<a href=#199 id=199 data-nosnippet>199</a> Statement::Explain(explain) =&gt; !explain.analyze || explain.statement.is_readonly(),
<a href=#200 id=200 data-nosnippet>200</a>
<a href=#201 id=201 data-nosnippet>201</a> <span class="comment">// Write operations
<a href=#202 id=202 data-nosnippet>202</a> </span>Statement::Insert(<span class="kw">_</span>)
<a href=#203 id=203 data-nosnippet>203</a> | Statement::Delete(<span class="kw">_</span>)
<a href=#204 id=204 data-nosnippet>204</a> | Statement::CreateTable(<span class="kw">_</span>)
<a href=#205 id=205 data-nosnippet>205</a> | Statement::CreateExternalTable(<span class="kw">_</span>)
<a href=#206 id=206 data-nosnippet>206</a> | Statement::CreateTableLike(<span class="kw">_</span>)
<a href=#207 id=207 data-nosnippet>207</a> | Statement::CreateFlow(<span class="kw">_</span>)
<a href=#208 id=208 data-nosnippet>208</a> | Statement::CreateView(<span class="kw">_</span>)
<a href=#209 id=209 data-nosnippet>209</a> | Statement::DropTable(<span class="kw">_</span>)
<a href=#210 id=210 data-nosnippet>210</a> | Statement::DropDatabase(<span class="kw">_</span>)
<a href=#211 id=211 data-nosnippet>211</a> | Statement::DropFlow(<span class="kw">_</span>)
<a href=#212 id=212 data-nosnippet>212</a> | Statement::DropView(<span class="kw">_</span>)
<a href=#213 id=213 data-nosnippet>213</a> | Statement::CreateDatabase(<span class="kw">_</span>)
<a href=#214 id=214 data-nosnippet>214</a> | Statement::AlterTable(<span class="kw">_</span>)
<a href=#215 id=215 data-nosnippet>215</a> | Statement::AlterDatabase(<span class="kw">_</span>)
<a href=#216 id=216 data-nosnippet>216</a> | Statement::Copy(<span class="kw">_</span>)
<a href=#217 id=217 data-nosnippet>217</a> | Statement::TruncateTable(<span class="kw">_</span>)
<a href=#218 id=218 data-nosnippet>218</a> | Statement::SetVariables(<span class="kw">_</span>)
<a href=#219 id=219 data-nosnippet>219</a> | Statement::Comment(<span class="kw">_</span>)
<a href=#220 id=220 data-nosnippet>220</a> | Statement::Use(<span class="kw">_</span>)
<a href=#221 id=221 data-nosnippet>221</a> | Statement::DeclareCursor(<span class="kw">_</span>)
<a href=#222 id=222 data-nosnippet>222</a> | Statement::CloseCursor(<span class="kw">_</span>)
<a href=#223 id=223 data-nosnippet>223</a> | Statement::Kill(<span class="kw">_</span>)
<a href=#224 id=224 data-nosnippet>224</a> | Statement::Admin(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<a href=#225 id=225 data-nosnippet>225</a>
<a href=#226 id=226 data-nosnippet>226</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#227 id=227 data-nosnippet>227</a> </span>Statement::UndropTable(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<a href=#228 id=228 data-nosnippet>228</a>
<a href=#229 id=229 data-nosnippet>229</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#230 id=230 data-nosnippet>230</a> </span>Statement::AlterTrigger(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<a href=#231 id=231 data-nosnippet>231</a>
<a href=#232 id=232 data-nosnippet>232</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#233 id=233 data-nosnippet>233</a> </span>Statement::CreateTrigger(<span class="kw">_</span>) | Statement::DropTrigger(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<a href=#234 id=234 data-nosnippet>234</a> }
<a href=#235 id=235 data-nosnippet>235</a> }
<a href=#236 id=236 data-nosnippet>236</a>}
<a href=#237 id=237 data-nosnippet>237</a>
<a href=#238 id=238 data-nosnippet>238</a><span class="kw">impl </span>Display <span class="kw">for </span>Statement {
<a href=#239 id=239 data-nosnippet>239</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#240 id=240 data-nosnippet>240</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#241 id=241 data-nosnippet>241</a> Statement::Query(s) =&gt; s.inner.fmt(f),
<a href=#242 id=242 data-nosnippet>242</a> Statement::Insert(s) =&gt; s.inner.fmt(f),
<a href=#243 id=243 data-nosnippet>243</a> Statement::Delete(s) =&gt; s.inner.fmt(f),
<a href=#244 id=244 data-nosnippet>244</a> Statement::CreateTable(s) =&gt; s.fmt(f),
<a href=#245 id=245 data-nosnippet>245</a> Statement::CreateExternalTable(s) =&gt; s.fmt(f),
<a href=#246 id=246 data-nosnippet>246</a> Statement::CreateTableLike(s) =&gt; s.fmt(f),
<a href=#247 id=247 data-nosnippet>247</a> Statement::CreateFlow(s) =&gt; s.fmt(f),
<a href=#248 id=248 data-nosnippet>248</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#249 id=249 data-nosnippet>249</a> </span>Statement::CreateTrigger(s) =&gt; s.fmt(f),
<a href=#250 id=250 data-nosnippet>250</a> Statement::DropFlow(s) =&gt; s.fmt(f),
<a href=#251 id=251 data-nosnippet>251</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#252 id=252 data-nosnippet>252</a> </span>Statement::DropTrigger(s) =&gt; s.fmt(f),
<a href=#253 id=253 data-nosnippet>253</a> Statement::DropTable(s) =&gt; s.fmt(f),
<a href=#254 id=254 data-nosnippet>254</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#255 id=255 data-nosnippet>255</a> </span>Statement::UndropTable(s) =&gt; s.fmt(f),
<a href=#256 id=256 data-nosnippet>256</a> Statement::DropDatabase(s) =&gt; s.fmt(f),
<a href=#257 id=257 data-nosnippet>257</a> Statement::DropView(s) =&gt; s.fmt(f),
<a href=#258 id=258 data-nosnippet>258</a> Statement::CreateDatabase(s) =&gt; s.fmt(f),
<a href=#259 id=259 data-nosnippet>259</a> Statement::AlterTable(s) =&gt; s.fmt(f),
<a href=#260 id=260 data-nosnippet>260</a> Statement::AlterDatabase(s) =&gt; s.fmt(f),
<a href=#261 id=261 data-nosnippet>261</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#262 id=262 data-nosnippet>262</a> </span>Statement::AlterTrigger(s) =&gt; s.fmt(f),
<a href=#263 id=263 data-nosnippet>263</a> Statement::ShowDatabases(s) =&gt; s.fmt(f),
<a href=#264 id=264 data-nosnippet>264</a> Statement::ShowTables(s) =&gt; s.fmt(f),
<a href=#265 id=265 data-nosnippet>265</a> Statement::ShowTableStatus(s) =&gt; s.fmt(f),
<a href=#266 id=266 data-nosnippet>266</a> Statement::ShowColumns(s) =&gt; s.fmt(f),
<a href=#267 id=267 data-nosnippet>267</a> Statement::ShowIndex(s) =&gt; s.fmt(f),
<a href=#268 id=268 data-nosnippet>268</a> Statement::ShowRegion(s) =&gt; s.fmt(f),
<a href=#269 id=269 data-nosnippet>269</a> Statement::ShowCreateTable(s) =&gt; s.fmt(f),
<a href=#270 id=270 data-nosnippet>270</a> Statement::ShowCreateFlow(s) =&gt; s.fmt(f),
<a href=#271 id=271 data-nosnippet>271</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#272 id=272 data-nosnippet>272</a> </span>Statement::ShowCreateTrigger(s) =&gt; s.fmt(f),
<a href=#273 id=273 data-nosnippet>273</a> Statement::ShowFlows(s) =&gt; s.fmt(f),
<a href=#274 id=274 data-nosnippet>274</a> Statement::ShowFlowStatus(s) =&gt; s.fmt(f),
<a href=#275 id=275 data-nosnippet>275</a> <span class="attr">#[cfg(feature = <span class="string">"enterprise"</span>)]
<a href=#276 id=276 data-nosnippet>276</a> </span>Statement::ShowTriggers(s) =&gt; s.fmt(f),
<a href=#277 id=277 data-nosnippet>277</a> Statement::ShowCreateDatabase(s) =&gt; s.fmt(f),
<a href=#278 id=278 data-nosnippet>278</a> Statement::ShowCreateView(s) =&gt; s.fmt(f),
<a href=#279 id=279 data-nosnippet>279</a> Statement::ShowViews(s) =&gt; s.fmt(f),
<a href=#280 id=280 data-nosnippet>280</a> Statement::ShowStatus(s) =&gt; s.fmt(f),
<a href=#281 id=281 data-nosnippet>281</a> Statement::ShowSearchPath(s) =&gt; s.fmt(f),
<a href=#282 id=282 data-nosnippet>282</a> Statement::DescribeTable(s) =&gt; s.fmt(f),
<a href=#283 id=283 data-nosnippet>283</a> Statement::Explain(s) =&gt; s.fmt(f),
<a href=#284 id=284 data-nosnippet>284</a> Statement::Copy(s) =&gt; s.fmt(f),
<a href=#285 id=285 data-nosnippet>285</a> Statement::Tql(s) =&gt; s.fmt(f),
<a href=#286 id=286 data-nosnippet>286</a> Statement::TruncateTable(s) =&gt; s.fmt(f),
<a href=#287 id=287 data-nosnippet>287</a> Statement::SetVariables(s) =&gt; s.fmt(f),
<a href=#288 id=288 data-nosnippet>288</a> Statement::ShowVariables(s) =&gt; s.fmt(f),
<a href=#289 id=289 data-nosnippet>289</a> Statement::Comment(s) =&gt; s.fmt(f),
<a href=#290 id=290 data-nosnippet>290</a> Statement::ShowCharset(kind) =&gt; {
<a href=#291 id=291 data-nosnippet>291</a> <span class="macro">write!</span>(f, <span class="string">"SHOW CHARSET {kind}"</span>)
<a href=#292 id=292 data-nosnippet>292</a> }
<a href=#293 id=293 data-nosnippet>293</a> Statement::ShowCollation(kind) =&gt; {
<a href=#294 id=294 data-nosnippet>294</a> <span class="macro">write!</span>(f, <span class="string">"SHOW COLLATION {kind}"</span>)
<a href=#295 id=295 data-nosnippet>295</a> }
<a href=#296 id=296 data-nosnippet>296</a> Statement::CreateView(s) =&gt; s.fmt(f),
<a href=#297 id=297 data-nosnippet>297</a> Statement::Use(s) =&gt; s.fmt(f),
<a href=#298 id=298 data-nosnippet>298</a> Statement::Admin(admin) =&gt; admin.fmt(f),
<a href=#299 id=299 data-nosnippet>299</a> Statement::DeclareCursor(s) =&gt; s.fmt(f),
<a href=#300 id=300 data-nosnippet>300</a> Statement::FetchCursor(s) =&gt; s.fmt(f),
<a href=#301 id=301 data-nosnippet>301</a> Statement::CloseCursor(s) =&gt; s.fmt(f),
<a href=#302 id=302 data-nosnippet>302</a> Statement::Kill(k) =&gt; k.fmt(f),
<a href=#303 id=303 data-nosnippet>303</a> Statement::ShowProcesslist(s) =&gt; s.fmt(f),
<a href=#304 id=304 data-nosnippet>304</a> }
<a href=#305 id=305 data-nosnippet>305</a> }
<a href=#306 id=306 data-nosnippet>306</a>}
<a href=#307 id=307 data-nosnippet>307</a>
<a href=#308 id=308 data-nosnippet>308</a><span class="doccomment">/// Comment hints from SQL.
<a href=#309 id=309 data-nosnippet>309</a>/// It'll be enabled when using `--comment` in mysql client.
<a href=#310 id=310 data-nosnippet>310</a>/// Eg: `SELECT * FROM system.number LIMIT 1; -- { ErrorCode 25 }`
<a href=#311 id=311 data-nosnippet>311</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq)]
<a href=#312 id=312 data-nosnippet>312</a></span><span class="kw">pub struct </span>Hint {
<a href=#313 id=313 data-nosnippet>313</a> <span class="kw">pub </span>error_code: <span class="prelude-ty">Option</span>&lt;u16&gt;,
<a href=#314 id=314 data-nosnippet>314</a> <span class="kw">pub </span>comment: String,
<a href=#315 id=315 data-nosnippet>315</a> <span class="kw">pub </span>prefix: String,
<a href=#316 id=316 data-nosnippet>316</a>}
<a href=#317 id=317 data-nosnippet>317</a>
<a href=#318 id=318 data-nosnippet>318</a><span class="kw">impl </span>TryFrom&lt;<span class="kw-2">&amp;</span>Statement&gt; <span class="kw">for </span>DfStatement {
<a href=#319 id=319 data-nosnippet>319</a> <span class="kw">type </span>Error = Error;
<a href=#320 id=320 data-nosnippet>320</a>
<a href=#321 id=321 data-nosnippet>321</a> <span class="kw">fn </span>try_from(s: <span class="kw-2">&amp;</span>Statement) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, <span class="self">Self</span>::Error&gt; {
<a href=#322 id=322 data-nosnippet>322</a> <span class="kw">let </span>s = <span class="kw">match </span>s {
<a href=#323 id=323 data-nosnippet>323</a> Statement::Query(query) =&gt; SpStatement::Query(Box::new(query.inner.clone())),
<a href=#324 id=324 data-nosnippet>324</a> Statement::Insert(insert) =&gt; insert.inner.clone(),
<a href=#325 id=325 data-nosnippet>325</a> Statement::Delete(delete) =&gt; delete.inner.clone(),
<a href=#326 id=326 data-nosnippet>326</a> <span class="kw">_ </span>=&gt; {
<a href=#327 id=327 data-nosnippet>327</a> <span class="kw">return </span>ConvertToDfStatementSnafu {
<a href=#328 id=328 data-nosnippet>328</a> statement: <span class="macro">format!</span>(<span class="string">"{s:?}"</span>),
<a href=#329 id=329 data-nosnippet>329</a> }
<a href=#330 id=330 data-nosnippet>330</a> .fail();
<a href=#331 id=331 data-nosnippet>331</a> }
<a href=#332 id=332 data-nosnippet>332</a> };
<a href=#333 id=333 data-nosnippet>333</a> <span class="prelude-val">Ok</span>(DfStatement::Statement(Box::new(s)))
<a href=#334 id=334 data-nosnippet>334</a> }
<a href=#335 id=335 data-nosnippet>335</a>}
</code></pre></div></section></main></body></html>
+234
View File
@@ -0,0 +1,234 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/tql.rs`."><title>tql.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>tql.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>serde::Serialize;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::AnalyzeFormat;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser_derive::{Visit, VisitMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#22 id=22 data-nosnippet>22</a></span><span class="kw">pub enum </span>Tql {
<a href=#23 id=23 data-nosnippet>23</a> Eval(TqlEval),
<a href=#24 id=24 data-nosnippet>24</a> Explain(TqlExplain),
<a href=#25 id=25 data-nosnippet>25</a> Analyze(TqlAnalyze),
<a href=#26 id=26 data-nosnippet>26</a>}
<a href=#27 id=27 data-nosnippet>27</a>
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">impl </span>Display <span class="kw">for </span>Tql {
<a href=#29 id=29 data-nosnippet>29</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#30 id=30 data-nosnippet>30</a> <span class="kw">match </span><span class="self">self </span>{
<a href=#31 id=31 data-nosnippet>31</a> Tql::Eval(t) =&gt; t.fmt(f),
<a href=#32 id=32 data-nosnippet>32</a> Tql::Explain(t) =&gt; t.fmt(f),
<a href=#33 id=33 data-nosnippet>33</a> Tql::Analyze(t) =&gt; t.fmt(f),
<a href=#34 id=34 data-nosnippet>34</a> }
<a href=#35 id=35 data-nosnippet>35</a> }
<a href=#36 id=36 data-nosnippet>36</a>}
<a href=#37 id=37 data-nosnippet>37</a>
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">fn </span>format_tql(
<a href=#39 id=39 data-nosnippet>39</a> f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;,
<a href=#40 id=40 data-nosnippet>40</a> start: <span class="kw-2">&amp;</span>str,
<a href=#41 id=41 data-nosnippet>41</a> end: <span class="kw-2">&amp;</span>str,
<a href=#42 id=42 data-nosnippet>42</a> step: <span class="kw-2">&amp;</span>str,
<a href=#43 id=43 data-nosnippet>43</a> lookback: <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>str&gt;,
<a href=#44 id=44 data-nosnippet>44</a> query: <span class="kw-2">&amp;</span>str,
<a href=#45 id=45 data-nosnippet>45</a> alias: <span class="kw-2">&amp;</span><span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#46 id=46 data-nosnippet>46</a>) -&gt; std::fmt::Result {
<a href=#47 id=47 data-nosnippet>47</a> <span class="macro">write!</span>(f, <span class="string">"({start}, {end}, '{step}'"</span>)<span class="question-mark">?</span>;
<a href=#48 id=48 data-nosnippet>48</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(lookback) = lookback {
<a href=#49 id=49 data-nosnippet>49</a> <span class="macro">write!</span>(f, <span class="string">", {lookback}"</span>)<span class="question-mark">?</span>;
<a href=#50 id=50 data-nosnippet>50</a> }
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(alias) = alias {
<a href=#52 id=52 data-nosnippet>52</a> <span class="macro">write!</span>(f, <span class="string">") {query} AS {alias}"</span>)
<a href=#53 id=53 data-nosnippet>53</a> } <span class="kw">else </span>{
<a href=#54 id=54 data-nosnippet>54</a> <span class="macro">write!</span>(f, <span class="string">") {query}"</span>)
<a href=#55 id=55 data-nosnippet>55</a> }
<a href=#56 id=56 data-nosnippet>56</a>}
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a><span class="doccomment">/// TQL EVAL (&lt;start&gt;, &lt;end&gt;, &lt;step&gt;, [lookback]) &lt;promql&gt; [AS alias]
<a href=#59 id=59 data-nosnippet>59</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#60 id=60 data-nosnippet>60</a></span><span class="kw">pub struct </span>TqlEval {
<a href=#61 id=61 data-nosnippet>61</a> <span class="kw">pub </span>start: String,
<a href=#62 id=62 data-nosnippet>62</a> <span class="kw">pub </span>end: String,
<a href=#63 id=63 data-nosnippet>63</a> <span class="kw">pub </span>step: String,
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">pub </span>lookback: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">pub </span>query: String,
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">pub </span>alias: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#67 id=67 data-nosnippet>67</a>}
<a href=#68 id=68 data-nosnippet>68</a>
<a href=#69 id=69 data-nosnippet>69</a><span class="kw">impl </span>Display <span class="kw">for </span>TqlEval {
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#71 id=71 data-nosnippet>71</a> <span class="macro">write!</span>(f, <span class="string">"TQL EVAL "</span>)<span class="question-mark">?</span>;
<a href=#72 id=72 data-nosnippet>72</a> format_tql(
<a href=#73 id=73 data-nosnippet>73</a> f,
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw-2">&amp;</span><span class="self">self</span>.start,
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw-2">&amp;</span><span class="self">self</span>.end,
<a href=#76 id=76 data-nosnippet>76</a> <span class="kw-2">&amp;</span><span class="self">self</span>.step,
<a href=#77 id=77 data-nosnippet>77</a> <span class="self">self</span>.lookback.as_deref(),
<a href=#78 id=78 data-nosnippet>78</a> <span class="kw-2">&amp;</span><span class="self">self</span>.query,
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw-2">&amp;</span><span class="self">self</span>.alias,
<a href=#80 id=80 data-nosnippet>80</a> )
<a href=#81 id=81 data-nosnippet>81</a> }
<a href=#82 id=82 data-nosnippet>82</a>}
<a href=#83 id=83 data-nosnippet>83</a>
<a href=#84 id=84 data-nosnippet>84</a><span class="doccomment">/// TQL EXPLAIN [VERBOSE] [FORMAT format] [&lt;start&gt;, &lt;end&gt;, &lt;step&gt;, [lookback]] &lt;promql&gt; [AS alias]
<a href=#85 id=85 data-nosnippet>85</a>/// doesn't execute the query but tells how the query would be executed (similar to SQL EXPLAIN).
<a href=#86 id=86 data-nosnippet>86</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#87 id=87 data-nosnippet>87</a></span><span class="kw">pub struct </span>TqlExplain {
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">pub </span>start: String,
<a href=#89 id=89 data-nosnippet>89</a> <span class="kw">pub </span>end: String,
<a href=#90 id=90 data-nosnippet>90</a> <span class="kw">pub </span>step: String,
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">pub </span>lookback: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#92 id=92 data-nosnippet>92</a> <span class="kw">pub </span>query: String,
<a href=#93 id=93 data-nosnippet>93</a> <span class="kw">pub </span>alias: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#94 id=94 data-nosnippet>94</a> <span class="kw">pub </span>is_verbose: bool,
<a href=#95 id=95 data-nosnippet>95</a> <span class="kw">pub </span>format: <span class="prelude-ty">Option</span>&lt;AnalyzeFormat&gt;,
<a href=#96 id=96 data-nosnippet>96</a>}
<a href=#97 id=97 data-nosnippet>97</a>
<a href=#98 id=98 data-nosnippet>98</a><span class="kw">impl </span>Display <span class="kw">for </span>TqlExplain {
<a href=#99 id=99 data-nosnippet>99</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#100 id=100 data-nosnippet>100</a> <span class="macro">write!</span>(f, <span class="string">"TQL EXPLAIN "</span>)<span class="question-mark">?</span>;
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">if </span><span class="self">self</span>.is_verbose {
<a href=#102 id=102 data-nosnippet>102</a> <span class="macro">write!</span>(f, <span class="string">"VERBOSE "</span>)<span class="question-mark">?</span>;
<a href=#103 id=103 data-nosnippet>103</a> }
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(format) = <span class="kw-2">&amp;</span><span class="self">self</span>.format {
<a href=#105 id=105 data-nosnippet>105</a> <span class="macro">write!</span>(f, <span class="string">"FORMAT {} "</span>, format)<span class="question-mark">?</span>;
<a href=#106 id=106 data-nosnippet>106</a> }
<a href=#107 id=107 data-nosnippet>107</a> format_tql(
<a href=#108 id=108 data-nosnippet>108</a> f,
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw-2">&amp;</span><span class="self">self</span>.start,
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw-2">&amp;</span><span class="self">self</span>.end,
<a href=#111 id=111 data-nosnippet>111</a> <span class="kw-2">&amp;</span><span class="self">self</span>.step,
<a href=#112 id=112 data-nosnippet>112</a> <span class="self">self</span>.lookback.as_deref(),
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw-2">&amp;</span><span class="self">self</span>.query,
<a href=#114 id=114 data-nosnippet>114</a> <span class="kw-2">&amp;</span><span class="self">self</span>.alias,
<a href=#115 id=115 data-nosnippet>115</a> )
<a href=#116 id=116 data-nosnippet>116</a> }
<a href=#117 id=117 data-nosnippet>117</a>}
<a href=#118 id=118 data-nosnippet>118</a>
<a href=#119 id=119 data-nosnippet>119</a><span class="doccomment">/// TQL ANALYZE [VERBOSE] [FORMAT format] (&lt;start&gt;, &lt;end&gt;, &lt;step&gt;, [lookback]) &lt;promql&gt; [AS alias]
<a href=#120 id=120 data-nosnippet>120</a>/// executes the plan and tells the detailed per-step execution time (similar to SQL ANALYZE).
<a href=#121 id=121 data-nosnippet>121</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
<a href=#122 id=122 data-nosnippet>122</a></span><span class="kw">pub struct </span>TqlAnalyze {
<a href=#123 id=123 data-nosnippet>123</a> <span class="kw">pub </span>start: String,
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">pub </span>end: String,
<a href=#125 id=125 data-nosnippet>125</a> <span class="kw">pub </span>step: String,
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">pub </span>lookback: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">pub </span>query: String,
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">pub </span>alias: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">pub </span>is_verbose: bool,
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">pub </span>format: <span class="prelude-ty">Option</span>&lt;AnalyzeFormat&gt;,
<a href=#131 id=131 data-nosnippet>131</a>}
<a href=#132 id=132 data-nosnippet>132</a>
<a href=#133 id=133 data-nosnippet>133</a><span class="kw">impl </span>Display <span class="kw">for </span>TqlAnalyze {
<a href=#134 id=134 data-nosnippet>134</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#135 id=135 data-nosnippet>135</a> <span class="macro">write!</span>(f, <span class="string">"TQL ANALYZE "</span>)<span class="question-mark">?</span>;
<a href=#136 id=136 data-nosnippet>136</a> <span class="kw">if </span><span class="self">self</span>.is_verbose {
<a href=#137 id=137 data-nosnippet>137</a> <span class="macro">write!</span>(f, <span class="string">"VERBOSE "</span>)<span class="question-mark">?</span>;
<a href=#138 id=138 data-nosnippet>138</a> }
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(format) = <span class="kw-2">&amp;</span><span class="self">self</span>.format {
<a href=#140 id=140 data-nosnippet>140</a> <span class="macro">write!</span>(f, <span class="string">"FORMAT {} "</span>, format)<span class="question-mark">?</span>;
<a href=#141 id=141 data-nosnippet>141</a> }
<a href=#142 id=142 data-nosnippet>142</a> format_tql(
<a href=#143 id=143 data-nosnippet>143</a> f,
<a href=#144 id=144 data-nosnippet>144</a> <span class="kw-2">&amp;</span><span class="self">self</span>.start,
<a href=#145 id=145 data-nosnippet>145</a> <span class="kw-2">&amp;</span><span class="self">self</span>.end,
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw-2">&amp;</span><span class="self">self</span>.step,
<a href=#147 id=147 data-nosnippet>147</a> <span class="self">self</span>.lookback.as_deref(),
<a href=#148 id=148 data-nosnippet>148</a> <span class="kw-2">&amp;</span><span class="self">self</span>.query,
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw-2">&amp;</span><span class="self">self</span>.alias,
<a href=#150 id=150 data-nosnippet>150</a> )
<a href=#151 id=151 data-nosnippet>151</a> }
<a href=#152 id=152 data-nosnippet>152</a>}
<a href=#153 id=153 data-nosnippet>153</a>
<a href=#154 id=154 data-nosnippet>154</a><span class="doccomment">/// Intermediate structure used to unify parameter mappings for various TQL operations.
<a href=#155 id=155 data-nosnippet>155</a>///
<a href=#156 id=156 data-nosnippet>156</a>/// This struct serves as a common parameter container for parsing TQL queries
<a href=#157 id=157 data-nosnippet>157</a>/// and constructing corresponding TQL operations: `TqlEval`, `TqlAnalyze` or `TqlExplain`.
<a href=#158 id=158 data-nosnippet>158</a></span><span class="attr">#[derive(Debug)]
<a href=#159 id=159 data-nosnippet>159</a></span><span class="kw">pub struct </span>TqlParameters {
<a href=#160 id=160 data-nosnippet>160</a> start: String,
<a href=#161 id=161 data-nosnippet>161</a> end: String,
<a href=#162 id=162 data-nosnippet>162</a> step: String,
<a href=#163 id=163 data-nosnippet>163</a> lookback: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#164 id=164 data-nosnippet>164</a> query: String,
<a href=#165 id=165 data-nosnippet>165</a> alias: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#166 id=166 data-nosnippet>166</a> <span class="kw">pub </span>is_verbose: bool,
<a href=#167 id=167 data-nosnippet>167</a> <span class="kw">pub </span>format: <span class="prelude-ty">Option</span>&lt;AnalyzeFormat&gt;,
<a href=#168 id=168 data-nosnippet>168</a>}
<a href=#169 id=169 data-nosnippet>169</a>
<a href=#170 id=170 data-nosnippet>170</a><span class="kw">impl </span>TqlParameters {
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">pub fn </span>new(
<a href=#172 id=172 data-nosnippet>172</a> start: String,
<a href=#173 id=173 data-nosnippet>173</a> end: String,
<a href=#174 id=174 data-nosnippet>174</a> step: String,
<a href=#175 id=175 data-nosnippet>175</a> lookback: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#176 id=176 data-nosnippet>176</a> query: String,
<a href=#177 id=177 data-nosnippet>177</a> alias: <span class="prelude-ty">Option</span>&lt;String&gt;,
<a href=#178 id=178 data-nosnippet>178</a> ) -&gt; <span class="self">Self </span>{
<a href=#179 id=179 data-nosnippet>179</a> TqlParameters {
<a href=#180 id=180 data-nosnippet>180</a> start,
<a href=#181 id=181 data-nosnippet>181</a> end,
<a href=#182 id=182 data-nosnippet>182</a> step,
<a href=#183 id=183 data-nosnippet>183</a> lookback,
<a href=#184 id=184 data-nosnippet>184</a> query,
<a href=#185 id=185 data-nosnippet>185</a> alias,
<a href=#186 id=186 data-nosnippet>186</a> is_verbose: <span class="bool-val">false</span>,
<a href=#187 id=187 data-nosnippet>187</a> format: <span class="prelude-val">None</span>,
<a href=#188 id=188 data-nosnippet>188</a> }
<a href=#189 id=189 data-nosnippet>189</a> }
<a href=#190 id=190 data-nosnippet>190</a>}
<a href=#191 id=191 data-nosnippet>191</a>
<a href=#192 id=192 data-nosnippet>192</a><span class="kw">impl </span>From&lt;TqlParameters&gt; <span class="kw">for </span>TqlEval {
<a href=#193 id=193 data-nosnippet>193</a> <span class="kw">fn </span>from(params: TqlParameters) -&gt; <span class="self">Self </span>{
<a href=#194 id=194 data-nosnippet>194</a> TqlEval {
<a href=#195 id=195 data-nosnippet>195</a> start: params.start,
<a href=#196 id=196 data-nosnippet>196</a> end: params.end,
<a href=#197 id=197 data-nosnippet>197</a> step: params.step,
<a href=#198 id=198 data-nosnippet>198</a> lookback: params.lookback,
<a href=#199 id=199 data-nosnippet>199</a> query: params.query,
<a href=#200 id=200 data-nosnippet>200</a> alias: params.alias,
<a href=#201 id=201 data-nosnippet>201</a> }
<a href=#202 id=202 data-nosnippet>202</a> }
<a href=#203 id=203 data-nosnippet>203</a>}
<a href=#204 id=204 data-nosnippet>204</a>
<a href=#205 id=205 data-nosnippet>205</a><span class="kw">impl </span>From&lt;TqlParameters&gt; <span class="kw">for </span>TqlExplain {
<a href=#206 id=206 data-nosnippet>206</a> <span class="kw">fn </span>from(params: TqlParameters) -&gt; <span class="self">Self </span>{
<a href=#207 id=207 data-nosnippet>207</a> TqlExplain {
<a href=#208 id=208 data-nosnippet>208</a> start: params.start,
<a href=#209 id=209 data-nosnippet>209</a> end: params.end,
<a href=#210 id=210 data-nosnippet>210</a> step: params.step,
<a href=#211 id=211 data-nosnippet>211</a> query: params.query,
<a href=#212 id=212 data-nosnippet>212</a> alias: params.alias,
<a href=#213 id=213 data-nosnippet>213</a> lookback: params.lookback,
<a href=#214 id=214 data-nosnippet>214</a> is_verbose: params.is_verbose,
<a href=#215 id=215 data-nosnippet>215</a> format: params.format,
<a href=#216 id=216 data-nosnippet>216</a> }
<a href=#217 id=217 data-nosnippet>217</a> }
<a href=#218 id=218 data-nosnippet>218</a>}
<a href=#219 id=219 data-nosnippet>219</a>
<a href=#220 id=220 data-nosnippet>220</a><span class="kw">impl </span>From&lt;TqlParameters&gt; <span class="kw">for </span>TqlAnalyze {
<a href=#221 id=221 data-nosnippet>221</a> <span class="kw">fn </span>from(params: TqlParameters) -&gt; <span class="self">Self </span>{
<a href=#222 id=222 data-nosnippet>222</a> TqlAnalyze {
<a href=#223 id=223 data-nosnippet>223</a> start: params.start,
<a href=#224 id=224 data-nosnippet>224</a> end: params.end,
<a href=#225 id=225 data-nosnippet>225</a> step: params.step,
<a href=#226 id=226 data-nosnippet>226</a> query: params.query,
<a href=#227 id=227 data-nosnippet>227</a> alias: params.alias,
<a href=#228 id=228 data-nosnippet>228</a> lookback: params.lookback,
<a href=#229 id=229 data-nosnippet>229</a> is_verbose: params.is_verbose,
<a href=#230 id=230 data-nosnippet>230</a> format: params.format,
<a href=#231 id=231 data-nosnippet>231</a> }
<a href=#232 id=232 data-nosnippet>232</a> }
<a href=#233 id=233 data-nosnippet>233</a>}
</code></pre></div></section></main></body></html>
+68
View File
@@ -0,0 +1,68 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/transform.rs`."><title>transform.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>transform.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">mod </span>expand_interval;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">mod </span>type_alias;
<a href=#17 id=17 data-nosnippet>17</a>
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>std::ops::ControlFlow;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>std::sync::Arc;
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>expand_interval::ExpandIntervalTransformRule;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>lazy_static::lazy_static;
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>sqlparser::ast::{Expr, visit_expressions_mut};
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span>type_alias::TypeAliasTransformRule;
<a href=#25 id=25 data-nosnippet>25</a>
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span><span class="kw">crate</span>::error::Result;
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#28 id=28 data-nosnippet>28</a>
<a href=#29 id=29 data-nosnippet>29</a><span class="macro">lazy_static!</span> {
<a href=#30 id=30 data-nosnippet>30</a> <span class="doccomment">/// [TransformRule] registry
<a href=#31 id=31 data-nosnippet>31</a> </span><span class="kw">static </span><span class="kw-2">ref </span>RULES: Vec&lt;Arc&lt;<span class="kw">dyn </span>TransformRule&gt;&gt; = <span class="macro">vec!</span>[
<a href=#32 id=32 data-nosnippet>32</a> Arc::new(ExpandIntervalTransformRule{}),
<a href=#33 id=33 data-nosnippet>33</a> Arc::new(TypeAliasTransformRule{}),
<a href=#34 id=34 data-nosnippet>34</a> ];
<a href=#35 id=35 data-nosnippet>35</a>}
<a href=#36 id=36 data-nosnippet>36</a>
<a href=#37 id=37 data-nosnippet>37</a><span class="doccomment">/// Transform rule to transform statement or expr
<a href=#38 id=38 data-nosnippet>38</a></span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">trait </span>TransformRule: Send + Sync {
<a href=#39 id=39 data-nosnippet>39</a> <span class="doccomment">/// Visit a [Statement]
<a href=#40 id=40 data-nosnippet>40</a> </span><span class="kw">fn </span>visit_statement(<span class="kw-2">&amp;</span><span class="self">self</span>, _stmt: <span class="kw-2">&amp;mut </span>Statement) -&gt; <span class="prelude-ty">Result</span>&lt;()&gt; {
<a href=#41 id=41 data-nosnippet>41</a> <span class="prelude-val">Ok</span>(())
<a href=#42 id=42 data-nosnippet>42</a> }
<a href=#43 id=43 data-nosnippet>43</a>
<a href=#44 id=44 data-nosnippet>44</a> <span class="doccomment">/// Visit an [Expr]
<a href=#45 id=45 data-nosnippet>45</a> </span><span class="kw">fn </span>visit_expr(<span class="kw-2">&amp;</span><span class="self">self</span>, _expr: <span class="kw-2">&amp;mut </span>Expr) -&gt; ControlFlow&lt;()&gt; {
<a href=#46 id=46 data-nosnippet>46</a> ControlFlow::&lt;()&gt;::Continue(())
<a href=#47 id=47 data-nosnippet>47</a> }
<a href=#48 id=48 data-nosnippet>48</a>}
<a href=#49 id=49 data-nosnippet>49</a>
<a href=#50 id=50 data-nosnippet>50</a><span class="doccomment">/// Transform statements by rules
<a href=#51 id=51 data-nosnippet>51</a></span><span class="kw">pub fn </span>transform_statements(stmts: <span class="kw-2">&amp;mut </span>Vec&lt;Statement&gt;) -&gt; <span class="prelude-ty">Result</span>&lt;()&gt; {
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">for </span>stmt <span class="kw">in </span><span class="kw-2">&amp;mut *</span>stmts {
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">for </span>rule <span class="kw">in </span>RULES.iter() {
<a href=#54 id=54 data-nosnippet>54</a> rule.visit_statement(stmt)<span class="question-mark">?</span>;
<a href=#55 id=55 data-nosnippet>55</a> }
<a href=#56 id=56 data-nosnippet>56</a> }
<a href=#57 id=57 data-nosnippet>57</a>
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">let _ </span>= visit_expressions_mut(stmts, |expr| {
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">for </span>rule <span class="kw">in </span>RULES.iter() {
<a href=#60 id=60 data-nosnippet>60</a> rule.visit_expr(expr)<span class="question-mark">?</span>;
<a href=#61 id=61 data-nosnippet>61</a> }
<a href=#62 id=62 data-nosnippet>62</a>
<a href=#63 id=63 data-nosnippet>63</a> ControlFlow::&lt;()&gt;::Continue(())
<a href=#64 id=64 data-nosnippet>64</a> });
<a href=#65 id=65 data-nosnippet>65</a>
<a href=#66 id=66 data-nosnippet>66</a> <span class="prelude-val">Ok</span>(())
<a href=#67 id=67 data-nosnippet>67</a>}
</code></pre></div></section></main></body></html>
@@ -0,0 +1,446 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/transform/expand_interval.rs`."><title>expand_interval.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../../" data-static-root-path="../../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../../static.files/src-script-813739b1.js"></script><script defer src="../../../../src-files.js"></script><script defer src="../../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/transform/</div>expand_interval.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::collections::HashMap;
<a href=#16 id=16 data-nosnippet>16</a><span class="kw">use </span>std::ops::ControlFlow;
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>std::time::Duration <span class="kw">as </span>StdDuration;
<a href=#18 id=18 data-nosnippet>18</a>
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>itertools::Itertools;
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>lazy_static::lazy_static;
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>regex::Regex;
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>sqlparser::ast::{DataType, Expr, Interval, Value, ValueWithSpan};
<a href=#23 id=23 data-nosnippet>23</a>
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span><span class="kw">crate</span>::statements::transform::TransformRule;
<a href=#25 id=25 data-nosnippet>25</a>
<a href=#26 id=26 data-nosnippet>26</a><span class="macro">lazy_static!</span> {
<a href=#27 id=27 data-nosnippet>27</a> <span class="doccomment">/// Matches either one or more digits `(\d+)` or one or more ASCII characters `[a-zA-Z]` or plus/minus signs
<a href=#28 id=28 data-nosnippet>28</a> </span><span class="kw">static </span><span class="kw-2">ref </span>INTERVAL_ABBREVIATION_PATTERN: Regex = Regex::new(<span class="string">r"([+-]?\d+|[a-zA-Z]+|\+|-)"</span>).unwrap();
<a href=#29 id=29 data-nosnippet>29</a>
<a href=#30 id=30 data-nosnippet>30</a> <span class="doccomment">/// Checks if the provided string starts as ISO_8601 format string (case/sign independent)
<a href=#31 id=31 data-nosnippet>31</a> </span><span class="kw">static </span><span class="kw-2">ref </span>IS_VALID_ISO_8601_PREFIX_PATTERN: Regex = Regex::new(<span class="string">r"^[-]?[Pp]"</span>).unwrap();
<a href=#32 id=32 data-nosnippet>32</a>
<a href=#33 id=33 data-nosnippet>33</a> <span class="kw">static </span><span class="kw-2">ref </span>INTERVAL_ABBREVIATION_MAPPING: HashMap&lt;<span class="kw-2">&amp;</span><span class="lifetime">'static </span>str, <span class="kw-2">&amp;</span><span class="lifetime">'static </span>str&gt; = HashMap::from([
<a href=#34 id=34 data-nosnippet>34</a> (<span class="string">"y"</span>,<span class="string">"years"</span>),
<a href=#35 id=35 data-nosnippet>35</a> (<span class="string">"mon"</span>,<span class="string">"months"</span>),
<a href=#36 id=36 data-nosnippet>36</a> (<span class="string">"w"</span>,<span class="string">"weeks"</span>),
<a href=#37 id=37 data-nosnippet>37</a> (<span class="string">"d"</span>,<span class="string">"days"</span>),
<a href=#38 id=38 data-nosnippet>38</a> (<span class="string">"h"</span>,<span class="string">"hours"</span>),
<a href=#39 id=39 data-nosnippet>39</a> (<span class="string">"m"</span>,<span class="string">"minutes"</span>),
<a href=#40 id=40 data-nosnippet>40</a> (<span class="string">"s"</span>,<span class="string">"seconds"</span>),
<a href=#41 id=41 data-nosnippet>41</a> (<span class="string">"millis"</span>,<span class="string">"milliseconds"</span>),
<a href=#42 id=42 data-nosnippet>42</a> (<span class="string">"ms"</span>,<span class="string">"milliseconds"</span>),
<a href=#43 id=43 data-nosnippet>43</a> (<span class="string">"us"</span>,<span class="string">"microseconds"</span>),
<a href=#44 id=44 data-nosnippet>44</a> (<span class="string">"ns"</span>,<span class="string">"nanoseconds"</span>),
<a href=#45 id=45 data-nosnippet>45</a> ]);
<a href=#46 id=46 data-nosnippet>46</a>}
<a href=#47 id=47 data-nosnippet>47</a>
<a href=#48 id=48 data-nosnippet>48</a><span class="doccomment">/// 'INTERVAL' abbreviation transformer
<a href=#49 id=49 data-nosnippet>49</a>/// - `y` for `years`
<a href=#50 id=50 data-nosnippet>50</a>/// - `mon` for `months`
<a href=#51 id=51 data-nosnippet>51</a>/// - `w` for `weeks`
<a href=#52 id=52 data-nosnippet>52</a>/// - `d` for `days`
<a href=#53 id=53 data-nosnippet>53</a>/// - `h` for `hours`
<a href=#54 id=54 data-nosnippet>54</a>/// - `m` for `minutes`
<a href=#55 id=55 data-nosnippet>55</a>/// - `s` for `seconds`
<a href=#56 id=56 data-nosnippet>56</a>/// - `millis` for `milliseconds`
<a href=#57 id=57 data-nosnippet>57</a>/// - `ms` for `milliseconds`
<a href=#58 id=58 data-nosnippet>58</a>/// - `us` for `microseconds`
<a href=#59 id=59 data-nosnippet>59</a>/// - `ns` for `nanoseconds`
<a href=#60 id=60 data-nosnippet>60</a>///
<a href=#61 id=61 data-nosnippet>61</a>/// Required for scenarios that use the shortened version of `INTERVAL`,
<a href=#62 id=62 data-nosnippet>62</a>/// f.e `SELECT INTERVAL '1h'` or `SELECT INTERVAL '3w2d'`
<a href=#63 id=63 data-nosnippet>63</a></span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">struct </span>ExpandIntervalTransformRule;
<a href=#64 id=64 data-nosnippet>64</a>
<a href=#65 id=65 data-nosnippet>65</a><span class="kw">impl </span>TransformRule <span class="kw">for </span>ExpandIntervalTransformRule {
<a href=#66 id=66 data-nosnippet>66</a> <span class="doccomment">/// Applies transform rule for `Interval` type by extending the shortened version (e.g. '1h', '2d') or
<a href=#67 id=67 data-nosnippet>67</a> /// converting ISO 8601 format strings (e.g., "P1Y2M3D")
<a href=#68 id=68 data-nosnippet>68</a> /// In case when `Interval` has `BinaryOp` value (e.g. query like `SELECT INTERVAL '2h' - INTERVAL '1h'`)
<a href=#69 id=69 data-nosnippet>69</a> /// it's AST has `left` part of type `Value::SingleQuotedString` which needs to be handled specifically.
<a href=#70 id=70 data-nosnippet>70</a> /// To handle the `right` part which is `Interval` no extra steps are needed.
<a href=#71 id=71 data-nosnippet>71</a> </span><span class="kw">fn </span>visit_expr(<span class="kw-2">&amp;</span><span class="self">self</span>, expr: <span class="kw-2">&amp;mut </span>Expr) -&gt; ControlFlow&lt;()&gt; {
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">match </span>expr {
<a href=#73 id=73 data-nosnippet>73</a> Expr::Interval(interval) =&gt; <span class="kw">match </span><span class="kw-2">&amp;*</span>interval.value {
<a href=#74 id=74 data-nosnippet>74</a> Expr::Value(ValueWithSpan {
<a href=#75 id=75 data-nosnippet>75</a> value: Value::SingleQuotedString(value),
<a href=#76 id=76 data-nosnippet>76</a> ..
<a href=#77 id=77 data-nosnippet>77</a> })
<a href=#78 id=78 data-nosnippet>78</a> | Expr::Value(ValueWithSpan {
<a href=#79 id=79 data-nosnippet>79</a> value: Value::DoubleQuotedString(value),
<a href=#80 id=80 data-nosnippet>80</a> ..
<a href=#81 id=81 data-nosnippet>81</a> }) =&gt; {
<a href=#82 id=82 data-nosnippet>82</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(normalized_name) = normalize_interval_name(value) {
<a href=#83 id=83 data-nosnippet>83</a> <span class="kw-2">*</span>expr = update_existing_interval_with_value(
<a href=#84 id=84 data-nosnippet>84</a> interval,
<a href=#85 id=85 data-nosnippet>85</a> single_quoted_string_expr(normalized_name),
<a href=#86 id=86 data-nosnippet>86</a> );
<a href=#87 id=87 data-nosnippet>87</a> }
<a href=#88 id=88 data-nosnippet>88</a> }
<a href=#89 id=89 data-nosnippet>89</a> Expr::BinaryOp { left, op, right } =&gt; <span class="kw">match </span><span class="kw-2">&amp;**</span>left {
<a href=#90 id=90 data-nosnippet>90</a> Expr::Value(ValueWithSpan {
<a href=#91 id=91 data-nosnippet>91</a> value: Value::SingleQuotedString(value),
<a href=#92 id=92 data-nosnippet>92</a> ..
<a href=#93 id=93 data-nosnippet>93</a> })
<a href=#94 id=94 data-nosnippet>94</a> | Expr::Value(ValueWithSpan {
<a href=#95 id=95 data-nosnippet>95</a> value: Value::DoubleQuotedString(value),
<a href=#96 id=96 data-nosnippet>96</a> ..
<a href=#97 id=97 data-nosnippet>97</a> }) =&gt; {
<a href=#98 id=98 data-nosnippet>98</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(normalized_name) = normalize_interval_name(value) {
<a href=#99 id=99 data-nosnippet>99</a> <span class="kw">let </span>new_expr_value = Box::new(Expr::BinaryOp {
<a href=#100 id=100 data-nosnippet>100</a> left: single_quoted_string_expr(normalized_name),
<a href=#101 id=101 data-nosnippet>101</a> op: op.clone(),
<a href=#102 id=102 data-nosnippet>102</a> right: right.clone(),
<a href=#103 id=103 data-nosnippet>103</a> });
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw-2">*</span>expr = update_existing_interval_with_value(interval, new_expr_value);
<a href=#105 id=105 data-nosnippet>105</a> }
<a href=#106 id=106 data-nosnippet>106</a> }
<a href=#107 id=107 data-nosnippet>107</a> <span class="kw">_ </span>=&gt; {}
<a href=#108 id=108 data-nosnippet>108</a> },
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw">_ </span>=&gt; {}
<a href=#110 id=110 data-nosnippet>110</a> },
<a href=#111 id=111 data-nosnippet>111</a> Expr::Cast {
<a href=#112 id=112 data-nosnippet>112</a> expr: cast_exp,
<a href=#113 id=113 data-nosnippet>113</a> data_type,
<a href=#114 id=114 data-nosnippet>114</a> array,
<a href=#115 id=115 data-nosnippet>115</a> kind,
<a href=#116 id=116 data-nosnippet>116</a> format,
<a href=#117 id=117 data-nosnippet>117</a> } =&gt; {
<a href=#118 id=118 data-nosnippet>118</a> <span class="kw">if </span><span class="macro">matches!</span>(data_type, DataType::Interval { .. }) {
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">match </span><span class="kw-2">&amp;**</span>cast_exp {
<a href=#120 id=120 data-nosnippet>120</a> Expr::Value(ValueWithSpan {
<a href=#121 id=121 data-nosnippet>121</a> value: Value::SingleQuotedString(value),
<a href=#122 id=122 data-nosnippet>122</a> ..
<a href=#123 id=123 data-nosnippet>123</a> })
<a href=#124 id=124 data-nosnippet>124</a> | Expr::Value(ValueWithSpan {
<a href=#125 id=125 data-nosnippet>125</a> value: Value::DoubleQuotedString(value),
<a href=#126 id=126 data-nosnippet>126</a> ..
<a href=#127 id=127 data-nosnippet>127</a> }) =&gt; {
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">let </span>interval_value =
<a href=#129 id=129 data-nosnippet>129</a> normalize_interval_name(value).unwrap_or_else(|| value.clone());
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw-2">*</span>expr = Expr::Cast {
<a href=#131 id=131 data-nosnippet>131</a> kind: kind.clone(),
<a href=#132 id=132 data-nosnippet>132</a> expr: single_quoted_string_expr(interval_value),
<a href=#133 id=133 data-nosnippet>133</a> data_type: data_type.clone(),
<a href=#134 id=134 data-nosnippet>134</a> array: <span class="kw-2">*</span>array,
<a href=#135 id=135 data-nosnippet>135</a> format: std::mem::take(format),
<a href=#136 id=136 data-nosnippet>136</a> }
<a href=#137 id=137 data-nosnippet>137</a> }
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">_ </span>=&gt; {}
<a href=#139 id=139 data-nosnippet>139</a> }
<a href=#140 id=140 data-nosnippet>140</a> }
<a href=#141 id=141 data-nosnippet>141</a> }
<a href=#142 id=142 data-nosnippet>142</a> <span class="kw">_ </span>=&gt; {}
<a href=#143 id=143 data-nosnippet>143</a> }
<a href=#144 id=144 data-nosnippet>144</a> ControlFlow::&lt;()&gt;::Continue(())
<a href=#145 id=145 data-nosnippet>145</a> }
<a href=#146 id=146 data-nosnippet>146</a>}
<a href=#147 id=147 data-nosnippet>147</a>
<a href=#148 id=148 data-nosnippet>148</a><span class="kw">fn </span>single_quoted_string_expr(string: String) -&gt; Box&lt;Expr&gt; {
<a href=#149 id=149 data-nosnippet>149</a> Box::new(Expr::Value(Value::SingleQuotedString(string).into()))
<a href=#150 id=150 data-nosnippet>150</a>}
<a href=#151 id=151 data-nosnippet>151</a>
<a href=#152 id=152 data-nosnippet>152</a><span class="kw">fn </span>update_existing_interval_with_value(interval: <span class="kw-2">&amp;</span>Interval, value: Box&lt;Expr&gt;) -&gt; Expr {
<a href=#153 id=153 data-nosnippet>153</a> Expr::Interval(Interval {
<a href=#154 id=154 data-nosnippet>154</a> value,
<a href=#155 id=155 data-nosnippet>155</a> leading_field: interval.leading_field.clone(),
<a href=#156 id=156 data-nosnippet>156</a> leading_precision: interval.leading_precision,
<a href=#157 id=157 data-nosnippet>157</a> last_field: interval.last_field.clone(),
<a href=#158 id=158 data-nosnippet>158</a> fractional_seconds_precision: interval.fractional_seconds_precision,
<a href=#159 id=159 data-nosnippet>159</a> })
<a href=#160 id=160 data-nosnippet>160</a>}
<a href=#161 id=161 data-nosnippet>161</a>
<a href=#162 id=162 data-nosnippet>162</a><span class="doccomment">/// Normalizes an interval expression string into the sql-compatible format.
<a href=#163 id=163 data-nosnippet>163</a>/// This function handles 2 types of input:
<a href=#164 id=164 data-nosnippet>164</a>/// 1. Abbreviated interval strings (e.g., "1y2mo3d")
<a href=#165 id=165 data-nosnippet>165</a>/// Returns an interval's full name (e.g., "years", "hours", "minutes") according to the `INTERVAL_ABBREVIATION_MAPPING`
<a href=#166 id=166 data-nosnippet>166</a>/// If the `interval_str` contains whitespaces, the interval name is considered to be in a full form.
<a href=#167 id=167 data-nosnippet>167</a>/// 2. ISO 8601 format strings (e.g., "P1Y2M3D"), case/sign independent
<a href=#168 id=168 data-nosnippet>168</a>/// Returns a number of milliseconds corresponding to ISO 8601 (e.g., "36525000 milliseconds")
<a href=#169 id=169 data-nosnippet>169</a>///
<a href=#170 id=170 data-nosnippet>170</a>/// Note: Hybrid format "1y 2 days 3h" is not supported.
<a href=#171 id=171 data-nosnippet>171</a></span><span class="kw">fn </span>normalize_interval_name(interval_str: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;String&gt; {
<a href=#172 id=172 data-nosnippet>172</a> <span class="kw">if </span>interval_str.contains(char::is_whitespace) {
<a href=#173 id=173 data-nosnippet>173</a> <span class="kw">return </span><span class="prelude-val">None</span>;
<a href=#174 id=174 data-nosnippet>174</a> }
<a href=#175 id=175 data-nosnippet>175</a>
<a href=#176 id=176 data-nosnippet>176</a> <span class="kw">if </span>IS_VALID_ISO_8601_PREFIX_PATTERN.is_match(interval_str) {
<a href=#177 id=177 data-nosnippet>177</a> <span class="kw">return </span>parse_iso8601_interval(interval_str);
<a href=#178 id=178 data-nosnippet>178</a> }
<a href=#179 id=179 data-nosnippet>179</a>
<a href=#180 id=180 data-nosnippet>180</a> expand_interval_abbreviation(interval_str)
<a href=#181 id=181 data-nosnippet>181</a>}
<a href=#182 id=182 data-nosnippet>182</a>
<a href=#183 id=183 data-nosnippet>183</a><span class="kw">fn </span>parse_iso8601_interval(signed_iso: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;String&gt; {
<a href=#184 id=184 data-nosnippet>184</a> <span class="kw">let </span>(is_negative, unsigned_iso) = <span class="kw">if let </span><span class="prelude-val">Some</span>(stripped) = signed_iso.strip_prefix(<span class="string">'-'</span>) {
<a href=#185 id=185 data-nosnippet>185</a> (<span class="bool-val">true</span>, stripped)
<a href=#186 id=186 data-nosnippet>186</a> } <span class="kw">else </span>{
<a href=#187 id=187 data-nosnippet>187</a> (<span class="bool-val">false</span>, signed_iso)
<a href=#188 id=188 data-nosnippet>188</a> };
<a href=#189 id=189 data-nosnippet>189</a>
<a href=#190 id=190 data-nosnippet>190</a> <span class="kw">match </span>iso8601::duration(<span class="kw-2">&amp;</span>unsigned_iso.to_uppercase()) {
<a href=#191 id=191 data-nosnippet>191</a> <span class="prelude-val">Ok</span>(duration) =&gt; {
<a href=#192 id=192 data-nosnippet>192</a> <span class="kw">let </span>millis = StdDuration::from(duration).as_millis();
<a href=#193 id=193 data-nosnippet>193</a> <span class="kw">let </span>sign = <span class="kw">if </span>is_negative { <span class="string">"-" </span>} <span class="kw">else </span>{ <span class="string">"" </span>};
<a href=#194 id=194 data-nosnippet>194</a> <span class="prelude-val">Some</span>(<span class="macro">format!</span>(<span class="string">"{}{} milliseconds"</span>, sign, millis))
<a href=#195 id=195 data-nosnippet>195</a> }
<a href=#196 id=196 data-nosnippet>196</a> <span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; <span class="prelude-val">None</span>,
<a href=#197 id=197 data-nosnippet>197</a> }
<a href=#198 id=198 data-nosnippet>198</a>}
<a href=#199 id=199 data-nosnippet>199</a>
<a href=#200 id=200 data-nosnippet>200</a><span class="kw">fn </span>expand_interval_abbreviation(interval_str: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;String&gt; {
<a href=#201 id=201 data-nosnippet>201</a> <span class="prelude-val">Some</span>(
<a href=#202 id=202 data-nosnippet>202</a> INTERVAL_ABBREVIATION_PATTERN
<a href=#203 id=203 data-nosnippet>203</a> .find_iter(interval_str)
<a href=#204 id=204 data-nosnippet>204</a> .map(|mat| {
<a href=#205 id=205 data-nosnippet>205</a> <span class="kw">let </span>mat_str = mat.as_str();
<a href=#206 id=206 data-nosnippet>206</a> <span class="kw-2">*</span>INTERVAL_ABBREVIATION_MAPPING
<a href=#207 id=207 data-nosnippet>207</a> .get(mat_str)
<a href=#208 id=208 data-nosnippet>208</a> .unwrap_or(<span class="kw-2">&amp;</span>mat_str)
<a href=#209 id=209 data-nosnippet>209</a> })
<a href=#210 id=210 data-nosnippet>210</a> .join(<span class="string">" "</span>),
<a href=#211 id=211 data-nosnippet>211</a> )
<a href=#212 id=212 data-nosnippet>212</a>}
<a href=#213 id=213 data-nosnippet>213</a>
<a href=#214 id=214 data-nosnippet>214</a><span class="attr">#[cfg(test)]
<a href=#215 id=215 data-nosnippet>215</a></span><span class="kw">mod </span>tests {
<a href=#216 id=216 data-nosnippet>216</a> <span class="kw">use </span>std::ops::ControlFlow;
<a href=#217 id=217 data-nosnippet>217</a>
<a href=#218 id=218 data-nosnippet>218</a> <span class="kw">use </span>sqlparser::ast::{BinaryOperator, CastKind, DataType, Expr, Interval, Value};
<a href=#219 id=219 data-nosnippet>219</a>
<a href=#220 id=220 data-nosnippet>220</a> <span class="kw">use </span><span class="kw">crate</span>::statements::transform::TransformRule;
<a href=#221 id=221 data-nosnippet>221</a> <span class="kw">use </span><span class="kw">crate</span>::statements::transform::expand_interval::{
<a href=#222 id=222 data-nosnippet>222</a> ExpandIntervalTransformRule, normalize_interval_name, single_quoted_string_expr,
<a href=#223 id=223 data-nosnippet>223</a> };
<a href=#224 id=224 data-nosnippet>224</a>
<a href=#225 id=225 data-nosnippet>225</a> <span class="kw">fn </span>create_interval(value: Box&lt;Expr&gt;) -&gt; Expr {
<a href=#226 id=226 data-nosnippet>226</a> Expr::Interval(Interval {
<a href=#227 id=227 data-nosnippet>227</a> value,
<a href=#228 id=228 data-nosnippet>228</a> leading_field: <span class="prelude-val">None</span>,
<a href=#229 id=229 data-nosnippet>229</a> leading_precision: <span class="prelude-val">None</span>,
<a href=#230 id=230 data-nosnippet>230</a> last_field: <span class="prelude-val">None</span>,
<a href=#231 id=231 data-nosnippet>231</a> fractional_seconds_precision: <span class="prelude-val">None</span>,
<a href=#232 id=232 data-nosnippet>232</a> })
<a href=#233 id=233 data-nosnippet>233</a> }
<a href=#234 id=234 data-nosnippet>234</a>
<a href=#235 id=235 data-nosnippet>235</a> <span class="attr">#[test]
<a href=#236 id=236 data-nosnippet>236</a> </span><span class="kw">fn </span>test_transform_interval_basic_conversions() {
<a href=#237 id=237 data-nosnippet>237</a> <span class="kw">let </span>test_cases = <span class="macro">vec!</span>[
<a href=#238 id=238 data-nosnippet>238</a> (<span class="string">"1y"</span>, <span class="string">"1 years"</span>),
<a href=#239 id=239 data-nosnippet>239</a> (<span class="string">"4mon"</span>, <span class="string">"4 months"</span>),
<a href=#240 id=240 data-nosnippet>240</a> (<span class="string">"-3w"</span>, <span class="string">"-3 weeks"</span>),
<a href=#241 id=241 data-nosnippet>241</a> (<span class="string">"55h"</span>, <span class="string">"55 hours"</span>),
<a href=#242 id=242 data-nosnippet>242</a> (<span class="string">"3d"</span>, <span class="string">"3 days"</span>),
<a href=#243 id=243 data-nosnippet>243</a> (<span class="string">"5s"</span>, <span class="string">"5 seconds"</span>),
<a href=#244 id=244 data-nosnippet>244</a> (<span class="string">"2m"</span>, <span class="string">"2 minutes"</span>),
<a href=#245 id=245 data-nosnippet>245</a> (<span class="string">"100millis"</span>, <span class="string">"100 milliseconds"</span>),
<a href=#246 id=246 data-nosnippet>246</a> (<span class="string">"200ms"</span>, <span class="string">"200 milliseconds"</span>),
<a href=#247 id=247 data-nosnippet>247</a> (<span class="string">"350us"</span>, <span class="string">"350 microseconds"</span>),
<a href=#248 id=248 data-nosnippet>248</a> (<span class="string">"400ns"</span>, <span class="string">"400 nanoseconds"</span>),
<a href=#249 id=249 data-nosnippet>249</a> ];
<a href=#250 id=250 data-nosnippet>250</a> <span class="kw">for </span>(input, expected) <span class="kw">in </span>test_cases {
<a href=#251 id=251 data-nosnippet>251</a> <span class="kw">let </span>result = normalize_interval_name(input).unwrap();
<a href=#252 id=252 data-nosnippet>252</a> <span class="macro">assert_eq!</span>(result, expected);
<a href=#253 id=253 data-nosnippet>253</a> }
<a href=#254 id=254 data-nosnippet>254</a>
<a href=#255 id=255 data-nosnippet>255</a> <span class="kw">let </span>test_cases = <span class="macro">vec!</span>[<span class="string">"1 year 2 months 3 days 4 hours"</span>, <span class="string">"-2 months"</span>];
<a href=#256 id=256 data-nosnippet>256</a> <span class="kw">for </span>input <span class="kw">in </span>test_cases {
<a href=#257 id=257 data-nosnippet>257</a> <span class="macro">assert_eq!</span>(normalize_interval_name(input), <span class="prelude-val">None</span>);
<a href=#258 id=258 data-nosnippet>258</a> }
<a href=#259 id=259 data-nosnippet>259</a> }
<a href=#260 id=260 data-nosnippet>260</a>
<a href=#261 id=261 data-nosnippet>261</a> <span class="attr">#[test]
<a href=#262 id=262 data-nosnippet>262</a> </span><span class="kw">fn </span>test_transform_interval_compound_conversions() {
<a href=#263 id=263 data-nosnippet>263</a> <span class="kw">let </span>test_cases = <span class="macro">vec!</span>[
<a href=#264 id=264 data-nosnippet>264</a> (<span class="string">"2y4mon6w"</span>, <span class="string">"2 years 4 months 6 weeks"</span>),
<a href=#265 id=265 data-nosnippet>265</a> (<span class="string">"5d3h1m"</span>, <span class="string">"5 days 3 hours 1 minutes"</span>),
<a href=#266 id=266 data-nosnippet>266</a> (
<a href=#267 id=267 data-nosnippet>267</a> <span class="string">"10s312ms789ns"</span>,
<a href=#268 id=268 data-nosnippet>268</a> <span class="string">"10 seconds 312 milliseconds 789 nanoseconds"</span>,
<a href=#269 id=269 data-nosnippet>269</a> ),
<a href=#270 id=270 data-nosnippet>270</a> (
<a href=#271 id=271 data-nosnippet>271</a> <span class="string">"23millis987us754ns"</span>,
<a href=#272 id=272 data-nosnippet>272</a> <span class="string">"23 milliseconds 987 microseconds 754 nanoseconds"</span>,
<a href=#273 id=273 data-nosnippet>273</a> ),
<a href=#274 id=274 data-nosnippet>274</a> (<span class="string">"-1d-5h"</span>, <span class="string">"-1 days -5 hours"</span>),
<a href=#275 id=275 data-nosnippet>275</a> (<span class="string">"-2y-4mon-6w"</span>, <span class="string">"-2 years -4 months -6 weeks"</span>),
<a href=#276 id=276 data-nosnippet>276</a> (<span class="string">"-5d-3h-1m"</span>, <span class="string">"-5 days -3 hours -1 minutes"</span>),
<a href=#277 id=277 data-nosnippet>277</a> (
<a href=#278 id=278 data-nosnippet>278</a> <span class="string">"-10s-312ms-789ns"</span>,
<a href=#279 id=279 data-nosnippet>279</a> <span class="string">"-10 seconds -312 milliseconds -789 nanoseconds"</span>,
<a href=#280 id=280 data-nosnippet>280</a> ),
<a href=#281 id=281 data-nosnippet>281</a> (
<a href=#282 id=282 data-nosnippet>282</a> <span class="string">"-23millis-987us-754ns"</span>,
<a href=#283 id=283 data-nosnippet>283</a> <span class="string">"-23 milliseconds -987 microseconds -754 nanoseconds"</span>,
<a href=#284 id=284 data-nosnippet>284</a> ),
<a href=#285 id=285 data-nosnippet>285</a> ];
<a href=#286 id=286 data-nosnippet>286</a> <span class="kw">for </span>(input, expected) <span class="kw">in </span>test_cases {
<a href=#287 id=287 data-nosnippet>287</a> <span class="kw">let </span>result = normalize_interval_name(input).unwrap();
<a href=#288 id=288 data-nosnippet>288</a> <span class="macro">assert_eq!</span>(result, expected);
<a href=#289 id=289 data-nosnippet>289</a> }
<a href=#290 id=290 data-nosnippet>290</a> }
<a href=#291 id=291 data-nosnippet>291</a>
<a href=#292 id=292 data-nosnippet>292</a> <span class="attr">#[test]
<a href=#293 id=293 data-nosnippet>293</a> </span><span class="kw">fn </span>test_iso8601_format() {
<a href=#294 id=294 data-nosnippet>294</a> <span class="macro">assert_eq!</span>(
<a href=#295 id=295 data-nosnippet>295</a> normalize_interval_name(<span class="string">"P1Y2M3DT4H5M6S"</span>),
<a href=#296 id=296 data-nosnippet>296</a> <span class="prelude-val">Some</span>(<span class="string">"36993906000 milliseconds"</span>.to_string())
<a href=#297 id=297 data-nosnippet>297</a> );
<a href=#298 id=298 data-nosnippet>298</a> <span class="macro">assert_eq!</span>(
<a href=#299 id=299 data-nosnippet>299</a> normalize_interval_name(<span class="string">"p3y3m700dt133h17m36.789s"</span>),
<a href=#300 id=300 data-nosnippet>300</a> <span class="prelude-val">Some</span>(<span class="string">"163343856789 milliseconds"</span>.to_string())
<a href=#301 id=301 data-nosnippet>301</a> );
<a href=#302 id=302 data-nosnippet>302</a> <span class="macro">assert_eq!</span>(
<a href=#303 id=303 data-nosnippet>303</a> normalize_interval_name(<span class="string">"-P1Y2M3DT4H5M6S"</span>),
<a href=#304 id=304 data-nosnippet>304</a> <span class="prelude-val">Some</span>(<span class="string">"-36993906000 milliseconds"</span>.to_string())
<a href=#305 id=305 data-nosnippet>305</a> );
<a href=#306 id=306 data-nosnippet>306</a> <span class="macro">assert_eq!</span>(normalize_interval_name(<span class="string">"P1_INVALID_ISO8601"</span>), <span class="prelude-val">None</span>);
<a href=#307 id=307 data-nosnippet>307</a> }
<a href=#308 id=308 data-nosnippet>308</a>
<a href=#309 id=309 data-nosnippet>309</a> <span class="attr">#[test]
<a href=#310 id=310 data-nosnippet>310</a> </span><span class="kw">fn </span>test_visit_expr_when_interval_is_single_quoted_string_abbr_expr() {
<a href=#311 id=311 data-nosnippet>311</a> <span class="kw">let </span>interval_transformation_rule = ExpandIntervalTransformRule {};
<a href=#312 id=312 data-nosnippet>312</a>
<a href=#313 id=313 data-nosnippet>313</a> <span class="kw">let </span><span class="kw-2">mut </span>string_expr = create_interval(single_quoted_string_expr(<span class="string">"5y"</span>.to_string()));
<a href=#314 id=314 data-nosnippet>314</a>
<a href=#315 id=315 data-nosnippet>315</a> <span class="kw">let </span>control_flow = interval_transformation_rule.visit_expr(<span class="kw-2">&amp;mut </span>string_expr);
<a href=#316 id=316 data-nosnippet>316</a>
<a href=#317 id=317 data-nosnippet>317</a> <span class="macro">assert_eq!</span>(control_flow, ControlFlow::Continue(()));
<a href=#318 id=318 data-nosnippet>318</a> <span class="macro">assert_eq!</span>(
<a href=#319 id=319 data-nosnippet>319</a> string_expr,
<a href=#320 id=320 data-nosnippet>320</a> Expr::Interval(Interval {
<a href=#321 id=321 data-nosnippet>321</a> value: Box::new(Expr::Value(
<a href=#322 id=322 data-nosnippet>322</a> Value::SingleQuotedString(<span class="string">"5 years"</span>.to_string()).into()
<a href=#323 id=323 data-nosnippet>323</a> )),
<a href=#324 id=324 data-nosnippet>324</a> leading_field: <span class="prelude-val">None</span>,
<a href=#325 id=325 data-nosnippet>325</a> leading_precision: <span class="prelude-val">None</span>,
<a href=#326 id=326 data-nosnippet>326</a> last_field: <span class="prelude-val">None</span>,
<a href=#327 id=327 data-nosnippet>327</a> fractional_seconds_precision: <span class="prelude-val">None</span>,
<a href=#328 id=328 data-nosnippet>328</a> })
<a href=#329 id=329 data-nosnippet>329</a> );
<a href=#330 id=330 data-nosnippet>330</a> }
<a href=#331 id=331 data-nosnippet>331</a>
<a href=#332 id=332 data-nosnippet>332</a> <span class="attr">#[test]
<a href=#333 id=333 data-nosnippet>333</a> </span><span class="kw">fn </span>test_visit_expr_when_interval_is_single_quoted_string_iso8601_expr() {
<a href=#334 id=334 data-nosnippet>334</a> <span class="kw">let </span>interval_transformation_rule = ExpandIntervalTransformRule {};
<a href=#335 id=335 data-nosnippet>335</a>
<a href=#336 id=336 data-nosnippet>336</a> <span class="kw">let </span><span class="kw-2">mut </span>string_expr =
<a href=#337 id=337 data-nosnippet>337</a> create_interval(single_quoted_string_expr(<span class="string">"P1Y2M3DT4H5M6S"</span>.to_string()));
<a href=#338 id=338 data-nosnippet>338</a>
<a href=#339 id=339 data-nosnippet>339</a> <span class="kw">let </span>control_flow = interval_transformation_rule.visit_expr(<span class="kw-2">&amp;mut </span>string_expr);
<a href=#340 id=340 data-nosnippet>340</a>
<a href=#341 id=341 data-nosnippet>341</a> <span class="macro">assert_eq!</span>(control_flow, ControlFlow::Continue(()));
<a href=#342 id=342 data-nosnippet>342</a> <span class="macro">assert_eq!</span>(
<a href=#343 id=343 data-nosnippet>343</a> string_expr,
<a href=#344 id=344 data-nosnippet>344</a> Expr::Interval(Interval {
<a href=#345 id=345 data-nosnippet>345</a> value: Box::new(Expr::Value(
<a href=#346 id=346 data-nosnippet>346</a> Value::SingleQuotedString(<span class="string">"36993906000 milliseconds"</span>.to_string()).into()
<a href=#347 id=347 data-nosnippet>347</a> )),
<a href=#348 id=348 data-nosnippet>348</a> leading_field: <span class="prelude-val">None</span>,
<a href=#349 id=349 data-nosnippet>349</a> leading_precision: <span class="prelude-val">None</span>,
<a href=#350 id=350 data-nosnippet>350</a> last_field: <span class="prelude-val">None</span>,
<a href=#351 id=351 data-nosnippet>351</a> fractional_seconds_precision: <span class="prelude-val">None</span>,
<a href=#352 id=352 data-nosnippet>352</a> })
<a href=#353 id=353 data-nosnippet>353</a> );
<a href=#354 id=354 data-nosnippet>354</a> }
<a href=#355 id=355 data-nosnippet>355</a>
<a href=#356 id=356 data-nosnippet>356</a> <span class="attr">#[test]
<a href=#357 id=357 data-nosnippet>357</a> </span><span class="kw">fn </span>test_visit_expr_when_interval_is_binary_op() {
<a href=#358 id=358 data-nosnippet>358</a> <span class="kw">let </span>interval_transformation_rule = ExpandIntervalTransformRule {};
<a href=#359 id=359 data-nosnippet>359</a>
<a href=#360 id=360 data-nosnippet>360</a> <span class="kw">let </span>binary_op = Box::new(Expr::BinaryOp {
<a href=#361 id=361 data-nosnippet>361</a> left: single_quoted_string_expr(<span class="string">"2d"</span>.to_string()),
<a href=#362 id=362 data-nosnippet>362</a> op: BinaryOperator::Minus,
<a href=#363 id=363 data-nosnippet>363</a> right: Box::new(create_interval(single_quoted_string_expr(<span class="string">"1d"</span>.to_string()))),
<a href=#364 id=364 data-nosnippet>364</a> });
<a href=#365 id=365 data-nosnippet>365</a> <span class="kw">let </span><span class="kw-2">mut </span>binary_op_expr = create_interval(binary_op);
<a href=#366 id=366 data-nosnippet>366</a> <span class="kw">let </span>control_flow = interval_transformation_rule.visit_expr(<span class="kw-2">&amp;mut </span>binary_op_expr);
<a href=#367 id=367 data-nosnippet>367</a>
<a href=#368 id=368 data-nosnippet>368</a> <span class="macro">assert_eq!</span>(control_flow, ControlFlow::Continue(()));
<a href=#369 id=369 data-nosnippet>369</a> <span class="macro">assert_eq!</span>(
<a href=#370 id=370 data-nosnippet>370</a> binary_op_expr,
<a href=#371 id=371 data-nosnippet>371</a> Expr::Interval(Interval {
<a href=#372 id=372 data-nosnippet>372</a> value: Box::new(Expr::BinaryOp {
<a href=#373 id=373 data-nosnippet>373</a> left: single_quoted_string_expr(<span class="string">"2 days"</span>.to_string()),
<a href=#374 id=374 data-nosnippet>374</a> op: BinaryOperator::Minus,
<a href=#375 id=375 data-nosnippet>375</a> right: Box::new(Expr::Interval(Interval {
<a href=#376 id=376 data-nosnippet>376</a> value: single_quoted_string_expr(<span class="string">"1d"</span>.to_string()),
<a href=#377 id=377 data-nosnippet>377</a> leading_field: <span class="prelude-val">None</span>,
<a href=#378 id=378 data-nosnippet>378</a> leading_precision: <span class="prelude-val">None</span>,
<a href=#379 id=379 data-nosnippet>379</a> last_field: <span class="prelude-val">None</span>,
<a href=#380 id=380 data-nosnippet>380</a> fractional_seconds_precision: <span class="prelude-val">None</span>,
<a href=#381 id=381 data-nosnippet>381</a> })),
<a href=#382 id=382 data-nosnippet>382</a> }),
<a href=#383 id=383 data-nosnippet>383</a> leading_field: <span class="prelude-val">None</span>,
<a href=#384 id=384 data-nosnippet>384</a> leading_precision: <span class="prelude-val">None</span>,
<a href=#385 id=385 data-nosnippet>385</a> last_field: <span class="prelude-val">None</span>,
<a href=#386 id=386 data-nosnippet>386</a> fractional_seconds_precision: <span class="prelude-val">None</span>,
<a href=#387 id=387 data-nosnippet>387</a> })
<a href=#388 id=388 data-nosnippet>388</a> );
<a href=#389 id=389 data-nosnippet>389</a> }
<a href=#390 id=390 data-nosnippet>390</a>
<a href=#391 id=391 data-nosnippet>391</a> <span class="attr">#[test]
<a href=#392 id=392 data-nosnippet>392</a> </span><span class="kw">fn </span>test_visit_expr_when_cast_expr() {
<a href=#393 id=393 data-nosnippet>393</a> <span class="kw">let </span>interval_transformation_rule = ExpandIntervalTransformRule {};
<a href=#394 id=394 data-nosnippet>394</a>
<a href=#395 id=395 data-nosnippet>395</a> <span class="kw">let </span><span class="kw-2">mut </span>cast_to_interval_expr = Expr::Cast {
<a href=#396 id=396 data-nosnippet>396</a> expr: single_quoted_string_expr(<span class="string">"3y2mon"</span>.to_string()),
<a href=#397 id=397 data-nosnippet>397</a> data_type: DataType::Interval {
<a href=#398 id=398 data-nosnippet>398</a> fields: <span class="prelude-val">None</span>,
<a href=#399 id=399 data-nosnippet>399</a> precision: <span class="prelude-val">None</span>,
<a href=#400 id=400 data-nosnippet>400</a> },
<a href=#401 id=401 data-nosnippet>401</a> array: <span class="bool-val">false</span>,
<a href=#402 id=402 data-nosnippet>402</a> format: <span class="prelude-val">None</span>,
<a href=#403 id=403 data-nosnippet>403</a> kind: sqlparser::ast::CastKind::Cast,
<a href=#404 id=404 data-nosnippet>404</a> };
<a href=#405 id=405 data-nosnippet>405</a>
<a href=#406 id=406 data-nosnippet>406</a> <span class="kw">let </span>control_flow = interval_transformation_rule.visit_expr(<span class="kw-2">&amp;mut </span>cast_to_interval_expr);
<a href=#407 id=407 data-nosnippet>407</a>
<a href=#408 id=408 data-nosnippet>408</a> <span class="macro">assert_eq!</span>(control_flow, ControlFlow::Continue(()));
<a href=#409 id=409 data-nosnippet>409</a> <span class="macro">assert_eq!</span>(
<a href=#410 id=410 data-nosnippet>410</a> cast_to_interval_expr,
<a href=#411 id=411 data-nosnippet>411</a> Expr::Cast {
<a href=#412 id=412 data-nosnippet>412</a> kind: CastKind::Cast,
<a href=#413 id=413 data-nosnippet>413</a> expr: Box::new(Expr::Value(
<a href=#414 id=414 data-nosnippet>414</a> Value::SingleQuotedString(<span class="string">"3 years 2 months"</span>.to_string()).into()
<a href=#415 id=415 data-nosnippet>415</a> )),
<a href=#416 id=416 data-nosnippet>416</a> data_type: DataType::Interval {
<a href=#417 id=417 data-nosnippet>417</a> fields: <span class="prelude-val">None</span>,
<a href=#418 id=418 data-nosnippet>418</a> precision: <span class="prelude-val">None</span>,
<a href=#419 id=419 data-nosnippet>419</a> },
<a href=#420 id=420 data-nosnippet>420</a> array: <span class="bool-val">false</span>,
<a href=#421 id=421 data-nosnippet>421</a> format: <span class="prelude-val">None</span>,
<a href=#422 id=422 data-nosnippet>422</a> }
<a href=#423 id=423 data-nosnippet>423</a> );
<a href=#424 id=424 data-nosnippet>424</a>
<a href=#425 id=425 data-nosnippet>425</a> <span class="kw">let </span><span class="kw-2">mut </span>cast_to_i64_expr = Expr::Cast {
<a href=#426 id=426 data-nosnippet>426</a> expr: single_quoted_string_expr(<span class="string">"5"</span>.to_string()),
<a href=#427 id=427 data-nosnippet>427</a> data_type: DataType::Int64,
<a href=#428 id=428 data-nosnippet>428</a> array: <span class="bool-val">false</span>,
<a href=#429 id=429 data-nosnippet>429</a> format: <span class="prelude-val">None</span>,
<a href=#430 id=430 data-nosnippet>430</a> kind: sqlparser::ast::CastKind::Cast,
<a href=#431 id=431 data-nosnippet>431</a> };
<a href=#432 id=432 data-nosnippet>432</a> <span class="kw">let </span>control_flow = interval_transformation_rule.visit_expr(<span class="kw-2">&amp;mut </span>cast_to_i64_expr);
<a href=#433 id=433 data-nosnippet>433</a> <span class="macro">assert_eq!</span>(control_flow, ControlFlow::Continue(()));
<a href=#434 id=434 data-nosnippet>434</a> <span class="macro">assert_eq!</span>(
<a href=#435 id=435 data-nosnippet>435</a> cast_to_i64_expr,
<a href=#436 id=436 data-nosnippet>436</a> Expr::Cast {
<a href=#437 id=437 data-nosnippet>437</a> expr: single_quoted_string_expr(<span class="string">"5"</span>.to_string()),
<a href=#438 id=438 data-nosnippet>438</a> data_type: DataType::Int64,
<a href=#439 id=439 data-nosnippet>439</a> array: <span class="bool-val">false</span>,
<a href=#440 id=440 data-nosnippet>440</a> format: <span class="prelude-val">None</span>,
<a href=#441 id=441 data-nosnippet>441</a> kind: sqlparser::ast::CastKind::Cast,
<a href=#442 id=442 data-nosnippet>442</a> }
<a href=#443 id=443 data-nosnippet>443</a> );
<a href=#444 id=444 data-nosnippet>444</a> }
<a href=#445 id=445 data-nosnippet>445</a>}
</code></pre></div></section></main></body></html>
@@ -0,0 +1,489 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/transform/type_alias.rs`."><title>type_alias.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../../" data-static-root-path="../../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../../static.files/src-script-813739b1.js"></script><script defer src="../../../../src-files.js"></script><script defer src="../../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/transform/</div>type_alias.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::ops::ControlFlow;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>datatypes::data_type::DataType <span class="kw">as </span>GreptimeDataType;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>sqlparser::ast::{
<a href=#19 id=19 data-nosnippet>19</a> DataType, ExactNumberInfo, Expr, Function, FunctionArg, FunctionArgExpr, FunctionArgumentList,
<a href=#20 id=20 data-nosnippet>20</a> Ident, ObjectName, Value,
<a href=#21 id=21 data-nosnippet>21</a>};
<a href=#22 id=22 data-nosnippet>22</a>
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span><span class="kw">crate</span>::ast::ObjectNamePartExt;
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span><span class="kw">crate</span>::error::Result;
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span><span class="kw">crate</span>::statements::alter::AlterTableOperation;
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span><span class="kw">crate</span>::statements::create::{CreateExternalTable, CreateTable};
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">use </span><span class="kw">crate</span>::statements::transform::TransformRule;
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">use </span><span class="kw">crate</span>::statements::{TimezoneInfo, sql_data_type_to_concrete_data_type};
<a href=#30 id=30 data-nosnippet>30</a>
<a href=#31 id=31 data-nosnippet>31</a><span class="doccomment">/// SQL data type alias transformer:
<a href=#32 id=32 data-nosnippet>32</a>/// - `TimestampSecond`, `Timestamp_s`, `Timestamp_sec` for `Timestamp(0)`.
<a href=#33 id=33 data-nosnippet>33</a>/// - `TimestampMillisecond`, `Timestamp_ms` for `Timestamp(3)`.
<a href=#34 id=34 data-nosnippet>34</a>/// - `TimestampMicrosecond`, `Timestamp_us` for `Timestamp(6)`.
<a href=#35 id=35 data-nosnippet>35</a>/// - `TimestampNanosecond`, `Timestamp_ns` for `Timestamp(9)`.
<a href=#36 id=36 data-nosnippet>36</a>/// - TinyText, MediumText, LongText for `Text`.
<a href=#37 id=37 data-nosnippet>37</a>///
<a href=#38 id=38 data-nosnippet>38</a>/// SQL dialect integer type aliases (MySQL &amp; PostgreSQL):
<a href=#39 id=39 data-nosnippet>39</a>/// - `INT2` for `smallint`
<a href=#40 id=40 data-nosnippet>40</a>/// - `INT4` for `int`
<a href=#41 id=41 data-nosnippet>41</a>/// - `INT8` for `bigint`
<a href=#42 id=42 data-nosnippet>42</a>/// - `FLOAT4` for `float`
<a href=#43 id=43 data-nosnippet>43</a>/// - `FLOAT8` for `double`
<a href=#44 id=44 data-nosnippet>44</a>///
<a href=#45 id=45 data-nosnippet>45</a>/// Extended type aliases for Arrow types:
<a href=#46 id=46 data-nosnippet>46</a>/// - `INT16` for `smallint`
<a href=#47 id=47 data-nosnippet>47</a>/// - `INT32` for `int`
<a href=#48 id=48 data-nosnippet>48</a>/// - `INT64` for `bigint`
<a href=#49 id=49 data-nosnippet>49</a>/// - And `UINT8`, `UINT16` etc. for `TinyIntUnsigned` etc.
<a href=#50 id=50 data-nosnippet>50</a>///
<a href=#51 id=51 data-nosnippet>51</a></span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">struct </span>TypeAliasTransformRule;
<a href=#52 id=52 data-nosnippet>52</a>
<a href=#53 id=53 data-nosnippet>53</a><span class="kw">impl </span>TransformRule <span class="kw">for </span>TypeAliasTransformRule {
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">fn </span>visit_statement(<span class="kw-2">&amp;</span><span class="self">self</span>, stmt: <span class="kw-2">&amp;mut </span>Statement) -&gt; <span class="prelude-ty">Result</span>&lt;()&gt; {
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">match </span>stmt {
<a href=#56 id=56 data-nosnippet>56</a> Statement::CreateTable(CreateTable { columns, .. }) =&gt; {
<a href=#57 id=57 data-nosnippet>57</a> columns
<a href=#58 id=58 data-nosnippet>58</a> .iter_mut()
<a href=#59 id=59 data-nosnippet>59</a> .for_each(|column| replace_type_alias(column.mut_data_type()));
<a href=#60 id=60 data-nosnippet>60</a> }
<a href=#61 id=61 data-nosnippet>61</a> Statement::CreateExternalTable(CreateExternalTable { columns, .. }) =&gt; {
<a href=#62 id=62 data-nosnippet>62</a> columns
<a href=#63 id=63 data-nosnippet>63</a> .iter_mut()
<a href=#64 id=64 data-nosnippet>64</a> .for_each(|column| replace_type_alias(column.mut_data_type()));
<a href=#65 id=65 data-nosnippet>65</a> }
<a href=#66 id=66 data-nosnippet>66</a> Statement::AlterTable(alter_table) =&gt; {
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">if let </span>AlterTableOperation::ModifyColumnType { target_type, .. } =
<a href=#68 id=68 data-nosnippet>68</a> alter_table.alter_operation_mut()
<a href=#69 id=69 data-nosnippet>69</a> {
<a href=#70 id=70 data-nosnippet>70</a> replace_type_alias(target_type)
<a href=#71 id=71 data-nosnippet>71</a> } <span class="kw">else if let </span>AlterTableOperation::AddColumns { add_columns, .. } =
<a href=#72 id=72 data-nosnippet>72</a> alter_table.alter_operation_mut()
<a href=#73 id=73 data-nosnippet>73</a> {
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">for </span>add_column <span class="kw">in </span>add_columns {
<a href=#75 id=75 data-nosnippet>75</a> replace_type_alias(add_column.column.mut_data_type());
<a href=#76 id=76 data-nosnippet>76</a> }
<a href=#77 id=77 data-nosnippet>77</a> }
<a href=#78 id=78 data-nosnippet>78</a> }
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw">_ </span>=&gt; {}
<a href=#80 id=80 data-nosnippet>80</a> }
<a href=#81 id=81 data-nosnippet>81</a>
<a href=#82 id=82 data-nosnippet>82</a> <span class="prelude-val">Ok</span>(())
<a href=#83 id=83 data-nosnippet>83</a> }
<a href=#84 id=84 data-nosnippet>84</a>
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">fn </span>visit_expr(<span class="kw-2">&amp;</span><span class="self">self</span>, expr: <span class="kw-2">&amp;mut </span>Expr) -&gt; ControlFlow&lt;()&gt; {
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">fn </span>cast_expr_to_arrow_cast_func(expr: Expr, cast_type: String) -&gt; Function {
<a href=#87 id=87 data-nosnippet>87</a> Function {
<a href=#88 id=88 data-nosnippet>88</a> name: ObjectName::from(<span class="macro">vec!</span>[Ident::new(<span class="string">"arrow_cast"</span>)]),
<a href=#89 id=89 data-nosnippet>89</a> args: sqlparser::ast::FunctionArguments::List(FunctionArgumentList {
<a href=#90 id=90 data-nosnippet>90</a> args: <span class="macro">vec!</span>[
<a href=#91 id=91 data-nosnippet>91</a> FunctionArg::Unnamed(FunctionArgExpr::Expr(expr)),
<a href=#92 id=92 data-nosnippet>92</a> FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
<a href=#93 id=93 data-nosnippet>93</a> Value::SingleQuotedString(cast_type).into(),
<a href=#94 id=94 data-nosnippet>94</a> ))),
<a href=#95 id=95 data-nosnippet>95</a> ],
<a href=#96 id=96 data-nosnippet>96</a> duplicate_treatment: <span class="prelude-val">None</span>,
<a href=#97 id=97 data-nosnippet>97</a> clauses: <span class="macro">vec!</span>[],
<a href=#98 id=98 data-nosnippet>98</a> }),
<a href=#99 id=99 data-nosnippet>99</a> filter: <span class="prelude-val">None</span>,
<a href=#100 id=100 data-nosnippet>100</a> null_treatment: <span class="prelude-val">None</span>,
<a href=#101 id=101 data-nosnippet>101</a> over: <span class="prelude-val">None</span>,
<a href=#102 id=102 data-nosnippet>102</a> parameters: sqlparser::ast::FunctionArguments::None,
<a href=#103 id=103 data-nosnippet>103</a> within_group: <span class="macro">vec!</span>[],
<a href=#104 id=104 data-nosnippet>104</a> uses_odbc_syntax: <span class="bool-val">false</span>,
<a href=#105 id=105 data-nosnippet>105</a> }
<a href=#106 id=106 data-nosnippet>106</a> }
<a href=#107 id=107 data-nosnippet>107</a>
<a href=#108 id=108 data-nosnippet>108</a> <span class="kw">match </span>expr {
<a href=#109 id=109 data-nosnippet>109</a> <span class="comment">// In new sqlparser, the "INT64" is no longer parsed to custom datatype.
<a href=#110 id=110 data-nosnippet>110</a> // The new "Int64" is not recognizable by Datafusion, cannot directly "CAST" to it.
<a href=#111 id=111 data-nosnippet>111</a> // We have to replace the expr to "arrow_cast" function call here.
<a href=#112 id=112 data-nosnippet>112</a> // Same for "FLOAT64".
<a href=#113 id=113 data-nosnippet>113</a> </span>Expr::Cast {
<a href=#114 id=114 data-nosnippet>114</a> expr: cast_expr,
<a href=#115 id=115 data-nosnippet>115</a> data_type,
<a href=#116 id=116 data-nosnippet>116</a> ..
<a href=#117 id=117 data-nosnippet>117</a> } <span class="kw">if </span>get_type_by_alias(data_type).is_some() =&gt; {
<a href=#118 id=118 data-nosnippet>118</a> <span class="comment">// Safety: checked in the match arm.
<a href=#119 id=119 data-nosnippet>119</a> </span><span class="kw">let </span>new_type = get_type_by_alias(data_type).unwrap();
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">if let </span><span class="prelude-val">Ok</span>(new_type) = sql_data_type_to_concrete_data_type(<span class="kw-2">&amp;</span>new_type) {
<a href=#121 id=121 data-nosnippet>121</a> <span class="kw-2">*</span>expr = Expr::Function(cast_expr_to_arrow_cast_func(
<a href=#122 id=122 data-nosnippet>122</a> (<span class="kw-2">**</span>cast_expr).clone(),
<a href=#123 id=123 data-nosnippet>123</a> new_type.as_arrow_type().to_string(),
<a href=#124 id=124 data-nosnippet>124</a> ));
<a href=#125 id=125 data-nosnippet>125</a> }
<a href=#126 id=126 data-nosnippet>126</a> }
<a href=#127 id=127 data-nosnippet>127</a>
<a href=#128 id=128 data-nosnippet>128</a> <span class="comment">// Timestamp(precision) in cast, datafusion doesn't support Timestamp(9) etc.
<a href=#129 id=129 data-nosnippet>129</a> // We have to transform it into arrow_cast(expr, type).
<a href=#130 id=130 data-nosnippet>130</a> </span>Expr::Cast {
<a href=#131 id=131 data-nosnippet>131</a> data_type: DataType::Timestamp(precision, zone),
<a href=#132 id=132 data-nosnippet>132</a> expr: cast_expr,
<a href=#133 id=133 data-nosnippet>133</a> ..
<a href=#134 id=134 data-nosnippet>134</a> } =&gt; {
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">if let </span><span class="prelude-val">Ok</span>(concrete_type) =
<a href=#136 id=136 data-nosnippet>136</a> sql_data_type_to_concrete_data_type(<span class="kw-2">&amp;</span>DataType::Timestamp(<span class="kw-2">*</span>precision, <span class="kw-2">*</span>zone))
<a href=#137 id=137 data-nosnippet>137</a> {
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">let </span>new_type = concrete_type.as_arrow_type();
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw-2">*</span>expr = Expr::Function(cast_expr_to_arrow_cast_func(
<a href=#140 id=140 data-nosnippet>140</a> (<span class="kw-2">**</span>cast_expr).clone(),
<a href=#141 id=141 data-nosnippet>141</a> new_type.to_string(),
<a href=#142 id=142 data-nosnippet>142</a> ));
<a href=#143 id=143 data-nosnippet>143</a> }
<a href=#144 id=144 data-nosnippet>144</a> }
<a href=#145 id=145 data-nosnippet>145</a>
<a href=#146 id=146 data-nosnippet>146</a> <span class="comment">// TODO(dennis): supports try_cast
<a href=#147 id=147 data-nosnippet>147</a> </span><span class="kw">_ </span>=&gt; {}
<a href=#148 id=148 data-nosnippet>148</a> }
<a href=#149 id=149 data-nosnippet>149</a>
<a href=#150 id=150 data-nosnippet>150</a> ControlFlow::&lt;()&gt;::Continue(())
<a href=#151 id=151 data-nosnippet>151</a> }
<a href=#152 id=152 data-nosnippet>152</a>}
<a href=#153 id=153 data-nosnippet>153</a>
<a href=#154 id=154 data-nosnippet>154</a><span class="kw">fn </span>replace_type_alias(data_type: <span class="kw-2">&amp;mut </span>DataType) {
<a href=#155 id=155 data-nosnippet>155</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(new_type) = get_type_by_alias(data_type) {
<a href=#156 id=156 data-nosnippet>156</a> <span class="kw-2">*</span>data_type = new_type;
<a href=#157 id=157 data-nosnippet>157</a> }
<a href=#158 id=158 data-nosnippet>158</a>}
<a href=#159 id=159 data-nosnippet>159</a>
<a href=#160 id=160 data-nosnippet>160</a><span class="doccomment">/// Get data type from alias type.
<a href=#161 id=161 data-nosnippet>161</a>/// Returns the mapped data type if the input data type is an alias that we need to replace.
<a href=#162 id=162 data-nosnippet>162</a></span><span class="comment">// Remember to update `get_data_type_by_alias_name()` if you modify this method.
<a href=#163 id=163 data-nosnippet>163</a></span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>get_type_by_alias(data_type: <span class="kw-2">&amp;</span>DataType) -&gt; <span class="prelude-ty">Option</span>&lt;DataType&gt; {
<a href=#164 id=164 data-nosnippet>164</a> <span class="kw">match </span>data_type {
<a href=#165 id=165 data-nosnippet>165</a> DataType::Custom(name, tokens) <span class="kw">if </span>name.<span class="number">0</span>.len() == <span class="number">1 </span>&amp;&amp; tokens.is_empty() =&gt; {
<a href=#166 id=166 data-nosnippet>166</a> get_data_type_by_alias_name(name.<span class="number">0</span>[<span class="number">0</span>].to_string_unquoted().as_str())
<a href=#167 id=167 data-nosnippet>167</a> }
<a href=#168 id=168 data-nosnippet>168</a> DataType::Int2(<span class="prelude-val">None</span>) =&gt; <span class="prelude-val">Some</span>(DataType::SmallInt(<span class="prelude-val">None</span>)),
<a href=#169 id=169 data-nosnippet>169</a> DataType::Int4(<span class="prelude-val">None</span>) =&gt; <span class="prelude-val">Some</span>(DataType::Int(<span class="prelude-val">None</span>)),
<a href=#170 id=170 data-nosnippet>170</a> DataType::Int8(<span class="prelude-val">None</span>) =&gt; <span class="prelude-val">Some</span>(DataType::BigInt(<span class="prelude-val">None</span>)),
<a href=#171 id=171 data-nosnippet>171</a> DataType::Int16 =&gt; <span class="prelude-val">Some</span>(DataType::SmallInt(<span class="prelude-val">None</span>)),
<a href=#172 id=172 data-nosnippet>172</a> DataType::Int32 =&gt; <span class="prelude-val">Some</span>(DataType::Int(<span class="prelude-val">None</span>)),
<a href=#173 id=173 data-nosnippet>173</a> DataType::Int64 =&gt; <span class="prelude-val">Some</span>(DataType::BigInt(<span class="prelude-val">None</span>)),
<a href=#174 id=174 data-nosnippet>174</a> DataType::UInt8 =&gt; <span class="prelude-val">Some</span>(DataType::TinyIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#175 id=175 data-nosnippet>175</a> DataType::UInt16 =&gt; <span class="prelude-val">Some</span>(DataType::SmallIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#176 id=176 data-nosnippet>176</a> DataType::UInt32 =&gt; <span class="prelude-val">Some</span>(DataType::IntUnsigned(<span class="prelude-val">None</span>)),
<a href=#177 id=177 data-nosnippet>177</a> DataType::UInt64 =&gt; <span class="prelude-val">Some</span>(DataType::BigIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#178 id=178 data-nosnippet>178</a> DataType::Float4 =&gt; <span class="prelude-val">Some</span>(DataType::Float(ExactNumberInfo::None)),
<a href=#179 id=179 data-nosnippet>179</a> DataType::Float8 =&gt; <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None)),
<a href=#180 id=180 data-nosnippet>180</a> DataType::Float32 =&gt; <span class="prelude-val">Some</span>(DataType::Float(ExactNumberInfo::None)),
<a href=#181 id=181 data-nosnippet>181</a> DataType::Float64 =&gt; <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None)),
<a href=#182 id=182 data-nosnippet>182</a> DataType::Bool =&gt; <span class="prelude-val">Some</span>(DataType::Boolean),
<a href=#183 id=183 data-nosnippet>183</a> DataType::Datetime(<span class="kw">_</span>) =&gt; <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">6</span>), TimezoneInfo::None)),
<a href=#184 id=184 data-nosnippet>184</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#185 id=185 data-nosnippet>185</a> }
<a href=#186 id=186 data-nosnippet>186</a>}
<a href=#187 id=187 data-nosnippet>187</a>
<a href=#188 id=188 data-nosnippet>188</a><span class="doccomment">/// Get the mapped data type from alias name.
<a href=#189 id=189 data-nosnippet>189</a>/// It only supports the following types of alias:
<a href=#190 id=190 data-nosnippet>190</a>/// - timestamps
<a href=#191 id=191 data-nosnippet>191</a>/// - ints
<a href=#192 id=192 data-nosnippet>192</a>/// - floats
<a href=#193 id=193 data-nosnippet>193</a>/// - texts
<a href=#194 id=194 data-nosnippet>194</a></span><span class="comment">// Remember to update `get_type_alias()` if you modify this method.
<a href=#195 id=195 data-nosnippet>195</a></span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>get_data_type_by_alias_name(name: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;DataType&gt; {
<a href=#196 id=196 data-nosnippet>196</a> <span class="kw">match </span>name.to_uppercase().as_ref() {
<a href=#197 id=197 data-nosnippet>197</a> <span class="comment">// Timestamp type alias
<a href=#198 id=198 data-nosnippet>198</a> </span><span class="string">"TIMESTAMP_S" </span>| <span class="string">"TIMESTAMP_SEC" </span>| <span class="string">"TIMESTAMPSECOND" </span>=&gt; {
<a href=#199 id=199 data-nosnippet>199</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">0</span>), TimezoneInfo::None))
<a href=#200 id=200 data-nosnippet>200</a> }
<a href=#201 id=201 data-nosnippet>201</a>
<a href=#202 id=202 data-nosnippet>202</a> <span class="string">"TIMESTAMP_MS" </span>| <span class="string">"TIMESTAMPMILLISECOND" </span>=&gt; {
<a href=#203 id=203 data-nosnippet>203</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">3</span>), TimezoneInfo::None))
<a href=#204 id=204 data-nosnippet>204</a> }
<a href=#205 id=205 data-nosnippet>205</a> <span class="string">"TIMESTAMP_US" </span>| <span class="string">"TIMESTAMPMICROSECOND" </span>| <span class="string">"DATETIME" </span>=&gt; {
<a href=#206 id=206 data-nosnippet>206</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">6</span>), TimezoneInfo::None))
<a href=#207 id=207 data-nosnippet>207</a> }
<a href=#208 id=208 data-nosnippet>208</a> <span class="string">"TIMESTAMP_NS" </span>| <span class="string">"TIMESTAMPNANOSECOND" </span>=&gt; {
<a href=#209 id=209 data-nosnippet>209</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">9</span>), TimezoneInfo::None))
<a href=#210 id=210 data-nosnippet>210</a> }
<a href=#211 id=211 data-nosnippet>211</a> <span class="comment">// Number type alias
<a href=#212 id=212 data-nosnippet>212</a> </span><span class="string">"INT2" </span>=&gt; <span class="prelude-val">Some</span>(DataType::SmallInt(<span class="prelude-val">None</span>)),
<a href=#213 id=213 data-nosnippet>213</a> <span class="string">"INT4" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Int(<span class="prelude-val">None</span>)),
<a href=#214 id=214 data-nosnippet>214</a> <span class="string">"INT8" </span>=&gt; <span class="prelude-val">Some</span>(DataType::BigInt(<span class="prelude-val">None</span>)),
<a href=#215 id=215 data-nosnippet>215</a> <span class="string">"INT16" </span>=&gt; <span class="prelude-val">Some</span>(DataType::SmallInt(<span class="prelude-val">None</span>)),
<a href=#216 id=216 data-nosnippet>216</a> <span class="string">"INT32" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Int(<span class="prelude-val">None</span>)),
<a href=#217 id=217 data-nosnippet>217</a> <span class="string">"INT64" </span>=&gt; <span class="prelude-val">Some</span>(DataType::BigInt(<span class="prelude-val">None</span>)),
<a href=#218 id=218 data-nosnippet>218</a> <span class="string">"UINT8" </span>=&gt; <span class="prelude-val">Some</span>(DataType::TinyIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#219 id=219 data-nosnippet>219</a> <span class="string">"UINT16" </span>=&gt; <span class="prelude-val">Some</span>(DataType::SmallIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#220 id=220 data-nosnippet>220</a> <span class="string">"UINT32" </span>=&gt; <span class="prelude-val">Some</span>(DataType::IntUnsigned(<span class="prelude-val">None</span>)),
<a href=#221 id=221 data-nosnippet>221</a> <span class="string">"UINT64" </span>=&gt; <span class="prelude-val">Some</span>(DataType::BigIntUnsigned(<span class="prelude-val">None</span>)),
<a href=#222 id=222 data-nosnippet>222</a> <span class="string">"FLOAT4" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Float(ExactNumberInfo::None)),
<a href=#223 id=223 data-nosnippet>223</a> <span class="string">"FLOAT8" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None)),
<a href=#224 id=224 data-nosnippet>224</a> <span class="string">"FLOAT32" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Float(ExactNumberInfo::None)),
<a href=#225 id=225 data-nosnippet>225</a> <span class="string">"FLOAT64" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None)),
<a href=#226 id=226 data-nosnippet>226</a> <span class="comment">// String type alias
<a href=#227 id=227 data-nosnippet>227</a> </span><span class="string">"TINYTEXT" </span>| <span class="string">"MEDIUMTEXT" </span>| <span class="string">"LONGTEXT" </span>=&gt; <span class="prelude-val">Some</span>(DataType::Text),
<a href=#228 id=228 data-nosnippet>228</a> <span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
<a href=#229 id=229 data-nosnippet>229</a> }
<a href=#230 id=230 data-nosnippet>230</a>}
<a href=#231 id=231 data-nosnippet>231</a>
<a href=#232 id=232 data-nosnippet>232</a><span class="attr">#[cfg(test)]
<a href=#233 id=233 data-nosnippet>233</a></span><span class="kw">mod </span>tests {
<a href=#234 id=234 data-nosnippet>234</a> <span class="kw">use </span>sqlparser::dialect::GenericDialect;
<a href=#235 id=235 data-nosnippet>235</a>
<a href=#236 id=236 data-nosnippet>236</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
<a href=#237 id=237 data-nosnippet>237</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#238 id=238 data-nosnippet>238</a> <span class="kw">use </span><span class="kw">crate</span>::statements::transform_statements;
<a href=#239 id=239 data-nosnippet>239</a>
<a href=#240 id=240 data-nosnippet>240</a> <span class="attr">#[test]
<a href=#241 id=241 data-nosnippet>241</a> </span><span class="kw">fn </span>test_get_data_type_by_alias_name() {
<a href=#242 id=242 data-nosnippet>242</a> <span class="macro">assert_eq!</span>(
<a href=#243 id=243 data-nosnippet>243</a> get_data_type_by_alias_name(<span class="string">"float64"</span>),
<a href=#244 id=244 data-nosnippet>244</a> <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None))
<a href=#245 id=245 data-nosnippet>245</a> );
<a href=#246 id=246 data-nosnippet>246</a> <span class="macro">assert_eq!</span>(
<a href=#247 id=247 data-nosnippet>247</a> get_data_type_by_alias_name(<span class="string">"Float64"</span>),
<a href=#248 id=248 data-nosnippet>248</a> <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None))
<a href=#249 id=249 data-nosnippet>249</a> );
<a href=#250 id=250 data-nosnippet>250</a> <span class="macro">assert_eq!</span>(
<a href=#251 id=251 data-nosnippet>251</a> get_data_type_by_alias_name(<span class="string">"FLOAT64"</span>),
<a href=#252 id=252 data-nosnippet>252</a> <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None))
<a href=#253 id=253 data-nosnippet>253</a> );
<a href=#254 id=254 data-nosnippet>254</a> <span class="macro">assert_eq!</span>(
<a href=#255 id=255 data-nosnippet>255</a> get_data_type_by_alias_name(<span class="string">"float32"</span>),
<a href=#256 id=256 data-nosnippet>256</a> <span class="prelude-val">Some</span>(DataType::Float(ExactNumberInfo::None))
<a href=#257 id=257 data-nosnippet>257</a> );
<a href=#258 id=258 data-nosnippet>258</a> <span class="macro">assert_eq!</span>(
<a href=#259 id=259 data-nosnippet>259</a> get_data_type_by_alias_name(<span class="string">"float8"</span>),
<a href=#260 id=260 data-nosnippet>260</a> <span class="prelude-val">Some</span>(DataType::Double(ExactNumberInfo::None))
<a href=#261 id=261 data-nosnippet>261</a> );
<a href=#262 id=262 data-nosnippet>262</a> <span class="macro">assert_eq!</span>(
<a href=#263 id=263 data-nosnippet>263</a> get_data_type_by_alias_name(<span class="string">"float4"</span>),
<a href=#264 id=264 data-nosnippet>264</a> <span class="prelude-val">Some</span>(DataType::Float(ExactNumberInfo::None))
<a href=#265 id=265 data-nosnippet>265</a> );
<a href=#266 id=266 data-nosnippet>266</a> <span class="macro">assert_eq!</span>(
<a href=#267 id=267 data-nosnippet>267</a> get_data_type_by_alias_name(<span class="string">"int8"</span>),
<a href=#268 id=268 data-nosnippet>268</a> <span class="prelude-val">Some</span>(DataType::BigInt(<span class="prelude-val">None</span>))
<a href=#269 id=269 data-nosnippet>269</a> );
<a href=#270 id=270 data-nosnippet>270</a> <span class="macro">assert_eq!</span>(
<a href=#271 id=271 data-nosnippet>271</a> get_data_type_by_alias_name(<span class="string">"int4"</span>),
<a href=#272 id=272 data-nosnippet>272</a> <span class="prelude-val">Some</span>(DataType::Int(<span class="prelude-val">None</span>))
<a href=#273 id=273 data-nosnippet>273</a> );
<a href=#274 id=274 data-nosnippet>274</a> <span class="macro">assert_eq!</span>(
<a href=#275 id=275 data-nosnippet>275</a> get_data_type_by_alias_name(<span class="string">"int2"</span>),
<a href=#276 id=276 data-nosnippet>276</a> <span class="prelude-val">Some</span>(DataType::SmallInt(<span class="prelude-val">None</span>))
<a href=#277 id=277 data-nosnippet>277</a> );
<a href=#278 id=278 data-nosnippet>278</a> <span class="macro">assert_eq!</span>(
<a href=#279 id=279 data-nosnippet>279</a> get_data_type_by_alias_name(<span class="string">"INT16"</span>),
<a href=#280 id=280 data-nosnippet>280</a> <span class="prelude-val">Some</span>(DataType::SmallInt(<span class="prelude-val">None</span>))
<a href=#281 id=281 data-nosnippet>281</a> );
<a href=#282 id=282 data-nosnippet>282</a> <span class="macro">assert_eq!</span>(
<a href=#283 id=283 data-nosnippet>283</a> get_data_type_by_alias_name(<span class="string">"INT32"</span>),
<a href=#284 id=284 data-nosnippet>284</a> <span class="prelude-val">Some</span>(DataType::Int(<span class="prelude-val">None</span>))
<a href=#285 id=285 data-nosnippet>285</a> );
<a href=#286 id=286 data-nosnippet>286</a> <span class="macro">assert_eq!</span>(
<a href=#287 id=287 data-nosnippet>287</a> get_data_type_by_alias_name(<span class="string">"INT64"</span>),
<a href=#288 id=288 data-nosnippet>288</a> <span class="prelude-val">Some</span>(DataType::BigInt(<span class="prelude-val">None</span>))
<a href=#289 id=289 data-nosnippet>289</a> );
<a href=#290 id=290 data-nosnippet>290</a> <span class="macro">assert_eq!</span>(
<a href=#291 id=291 data-nosnippet>291</a> get_data_type_by_alias_name(<span class="string">"Uint8"</span>),
<a href=#292 id=292 data-nosnippet>292</a> <span class="prelude-val">Some</span>(DataType::TinyIntUnsigned(<span class="prelude-val">None</span>))
<a href=#293 id=293 data-nosnippet>293</a> );
<a href=#294 id=294 data-nosnippet>294</a> <span class="macro">assert_eq!</span>(
<a href=#295 id=295 data-nosnippet>295</a> get_data_type_by_alias_name(<span class="string">"UINT16"</span>),
<a href=#296 id=296 data-nosnippet>296</a> <span class="prelude-val">Some</span>(DataType::SmallIntUnsigned(<span class="prelude-val">None</span>))
<a href=#297 id=297 data-nosnippet>297</a> );
<a href=#298 id=298 data-nosnippet>298</a> <span class="macro">assert_eq!</span>(
<a href=#299 id=299 data-nosnippet>299</a> get_data_type_by_alias_name(<span class="string">"UINT32"</span>),
<a href=#300 id=300 data-nosnippet>300</a> <span class="prelude-val">Some</span>(DataType::IntUnsigned(<span class="prelude-val">None</span>))
<a href=#301 id=301 data-nosnippet>301</a> );
<a href=#302 id=302 data-nosnippet>302</a> <span class="macro">assert_eq!</span>(
<a href=#303 id=303 data-nosnippet>303</a> get_data_type_by_alias_name(<span class="string">"uint64"</span>),
<a href=#304 id=304 data-nosnippet>304</a> <span class="prelude-val">Some</span>(DataType::BigIntUnsigned(<span class="prelude-val">None</span>))
<a href=#305 id=305 data-nosnippet>305</a> );
<a href=#306 id=306 data-nosnippet>306</a>
<a href=#307 id=307 data-nosnippet>307</a> <span class="macro">assert_eq!</span>(
<a href=#308 id=308 data-nosnippet>308</a> get_data_type_by_alias_name(<span class="string">"TimestampSecond"</span>),
<a href=#309 id=309 data-nosnippet>309</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">0</span>), TimezoneInfo::None))
<a href=#310 id=310 data-nosnippet>310</a> );
<a href=#311 id=311 data-nosnippet>311</a> <span class="macro">assert_eq!</span>(
<a href=#312 id=312 data-nosnippet>312</a> get_data_type_by_alias_name(<span class="string">"Timestamp_s"</span>),
<a href=#313 id=313 data-nosnippet>313</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">0</span>), TimezoneInfo::None))
<a href=#314 id=314 data-nosnippet>314</a> );
<a href=#315 id=315 data-nosnippet>315</a> <span class="macro">assert_eq!</span>(
<a href=#316 id=316 data-nosnippet>316</a> get_data_type_by_alias_name(<span class="string">"Timestamp_sec"</span>),
<a href=#317 id=317 data-nosnippet>317</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">0</span>), TimezoneInfo::None))
<a href=#318 id=318 data-nosnippet>318</a> );
<a href=#319 id=319 data-nosnippet>319</a>
<a href=#320 id=320 data-nosnippet>320</a> <span class="macro">assert_eq!</span>(
<a href=#321 id=321 data-nosnippet>321</a> get_data_type_by_alias_name(<span class="string">"TimestampMilliSecond"</span>),
<a href=#322 id=322 data-nosnippet>322</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">3</span>), TimezoneInfo::None))
<a href=#323 id=323 data-nosnippet>323</a> );
<a href=#324 id=324 data-nosnippet>324</a> <span class="macro">assert_eq!</span>(
<a href=#325 id=325 data-nosnippet>325</a> get_data_type_by_alias_name(<span class="string">"Timestamp_ms"</span>),
<a href=#326 id=326 data-nosnippet>326</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">3</span>), TimezoneInfo::None))
<a href=#327 id=327 data-nosnippet>327</a> );
<a href=#328 id=328 data-nosnippet>328</a>
<a href=#329 id=329 data-nosnippet>329</a> <span class="macro">assert_eq!</span>(
<a href=#330 id=330 data-nosnippet>330</a> get_data_type_by_alias_name(<span class="string">"TimestampMicroSecond"</span>),
<a href=#331 id=331 data-nosnippet>331</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">6</span>), TimezoneInfo::None))
<a href=#332 id=332 data-nosnippet>332</a> );
<a href=#333 id=333 data-nosnippet>333</a> <span class="macro">assert_eq!</span>(
<a href=#334 id=334 data-nosnippet>334</a> get_data_type_by_alias_name(<span class="string">"Timestamp_us"</span>),
<a href=#335 id=335 data-nosnippet>335</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">6</span>), TimezoneInfo::None))
<a href=#336 id=336 data-nosnippet>336</a> );
<a href=#337 id=337 data-nosnippet>337</a>
<a href=#338 id=338 data-nosnippet>338</a> <span class="macro">assert_eq!</span>(
<a href=#339 id=339 data-nosnippet>339</a> get_data_type_by_alias_name(<span class="string">"TimestampNanoSecond"</span>),
<a href=#340 id=340 data-nosnippet>340</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">9</span>), TimezoneInfo::None))
<a href=#341 id=341 data-nosnippet>341</a> );
<a href=#342 id=342 data-nosnippet>342</a> <span class="macro">assert_eq!</span>(
<a href=#343 id=343 data-nosnippet>343</a> get_data_type_by_alias_name(<span class="string">"Timestamp_ns"</span>),
<a href=#344 id=344 data-nosnippet>344</a> <span class="prelude-val">Some</span>(DataType::Timestamp(<span class="prelude-val">Some</span>(<span class="number">9</span>), TimezoneInfo::None))
<a href=#345 id=345 data-nosnippet>345</a> );
<a href=#346 id=346 data-nosnippet>346</a> <span class="macro">assert_eq!</span>(
<a href=#347 id=347 data-nosnippet>347</a> get_data_type_by_alias_name(<span class="string">"TinyText"</span>),
<a href=#348 id=348 data-nosnippet>348</a> <span class="prelude-val">Some</span>(DataType::Text)
<a href=#349 id=349 data-nosnippet>349</a> );
<a href=#350 id=350 data-nosnippet>350</a> <span class="macro">assert_eq!</span>(
<a href=#351 id=351 data-nosnippet>351</a> get_data_type_by_alias_name(<span class="string">"MediumText"</span>),
<a href=#352 id=352 data-nosnippet>352</a> <span class="prelude-val">Some</span>(DataType::Text)
<a href=#353 id=353 data-nosnippet>353</a> );
<a href=#354 id=354 data-nosnippet>354</a> <span class="macro">assert_eq!</span>(
<a href=#355 id=355 data-nosnippet>355</a> get_data_type_by_alias_name(<span class="string">"LongText"</span>),
<a href=#356 id=356 data-nosnippet>356</a> <span class="prelude-val">Some</span>(DataType::Text)
<a href=#357 id=357 data-nosnippet>357</a> );
<a href=#358 id=358 data-nosnippet>358</a> }
<a href=#359 id=359 data-nosnippet>359</a>
<a href=#360 id=360 data-nosnippet>360</a> <span class="kw">fn </span>test_timestamp_alias(alias: <span class="kw-2">&amp;</span>str, expected: <span class="kw-2">&amp;</span>str) {
<a href=#361 id=361 data-nosnippet>361</a> <span class="kw">let </span>sql = <span class="macro">format!</span>(<span class="string">"SELECT TIMESTAMP '2020-01-01 01:23:45.12345678'::{alias}"</span>);
<a href=#362 id=362 data-nosnippet>362</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#363 id=363 data-nosnippet>363</a> ParserContext::create_with_dialect(<span class="kw-2">&amp;</span>sql, <span class="kw-2">&amp;</span>GenericDialect {}, ParseOptions::default())
<a href=#364 id=364 data-nosnippet>364</a> .unwrap();
<a href=#365 id=365 data-nosnippet>365</a> transform_statements(<span class="kw-2">&amp;mut </span>stmts).unwrap();
<a href=#366 id=366 data-nosnippet>366</a>
<a href=#367 id=367 data-nosnippet>367</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#368 id=368 data-nosnippet>368</a> Statement::Query(q) =&gt; <span class="macro">assert_eq!</span>(
<a href=#369 id=369 data-nosnippet>369</a> <span class="macro">format!</span>(
<a href=#370 id=370 data-nosnippet>370</a> <span class="string">"SELECT arrow_cast(TIMESTAMP '2020-01-01 01:23:45.12345678', 'Timestamp({expected})')"
<a href=#371 id=371 data-nosnippet>371</a> </span>),
<a href=#372 id=372 data-nosnippet>372</a> q.to_string()
<a href=#373 id=373 data-nosnippet>373</a> ),
<a href=#374 id=374 data-nosnippet>374</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#375 id=375 data-nosnippet>375</a> }
<a href=#376 id=376 data-nosnippet>376</a> }
<a href=#377 id=377 data-nosnippet>377</a>
<a href=#378 id=378 data-nosnippet>378</a> <span class="kw">fn </span>test_timestamp_precision_type(precision: i32, expected: <span class="kw-2">&amp;</span>str) {
<a href=#379 id=379 data-nosnippet>379</a> test_timestamp_alias(<span class="kw-2">&amp;</span><span class="macro">format!</span>(<span class="string">"Timestamp({precision})"</span>), expected);
<a href=#380 id=380 data-nosnippet>380</a> }
<a href=#381 id=381 data-nosnippet>381</a>
<a href=#382 id=382 data-nosnippet>382</a> <span class="attr">#[test]
<a href=#383 id=383 data-nosnippet>383</a> </span><span class="kw">fn </span>test_boolean_alias() {
<a href=#384 id=384 data-nosnippet>384</a> <span class="kw">let </span>sql = <span class="string">"CREATE TABLE test(b bool, ts TIMESTAMP TIME INDEX)"</span>;
<a href=#385 id=385 data-nosnippet>385</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#386 id=386 data-nosnippet>386</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GenericDialect {}, ParseOptions::default())
<a href=#387 id=387 data-nosnippet>387</a> .unwrap();
<a href=#388 id=388 data-nosnippet>388</a> transform_statements(<span class="kw-2">&amp;mut </span>stmts).unwrap();
<a href=#389 id=389 data-nosnippet>389</a>
<a href=#390 id=390 data-nosnippet>390</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#391 id=391 data-nosnippet>391</a> Statement::CreateTable(c) =&gt; <span class="macro">assert_eq!</span>(
<a href=#392 id=392 data-nosnippet>392</a> <span class="string">"CREATE TABLE test (\n b BOOLEAN,\n ts TIMESTAMP NOT NULL,\n TIME INDEX (ts)\n)\nENGINE=mito\n"</span>,
<a href=#393 id=393 data-nosnippet>393</a> c.to_string()
<a href=#394 id=394 data-nosnippet>394</a> ),
<a href=#395 id=395 data-nosnippet>395</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#396 id=396 data-nosnippet>396</a> }
<a href=#397 id=397 data-nosnippet>397</a> }
<a href=#398 id=398 data-nosnippet>398</a>
<a href=#399 id=399 data-nosnippet>399</a> <span class="attr">#[test]
<a href=#400 id=400 data-nosnippet>400</a> </span><span class="kw">fn </span>test_transform_timestamp_alias() {
<a href=#401 id=401 data-nosnippet>401</a> <span class="comment">// Timestamp[Second | Millisecond | Microsecond | Nanosecond]
<a href=#402 id=402 data-nosnippet>402</a> </span>test_timestamp_alias(<span class="string">"TimestampSecond"</span>, <span class="string">"s"</span>);
<a href=#403 id=403 data-nosnippet>403</a> test_timestamp_alias(<span class="string">"Timestamp_s"</span>, <span class="string">"s"</span>);
<a href=#404 id=404 data-nosnippet>404</a> test_timestamp_alias(<span class="string">"TimestampMillisecond"</span>, <span class="string">"ms"</span>);
<a href=#405 id=405 data-nosnippet>405</a> test_timestamp_alias(<span class="string">"Timestamp_ms"</span>, <span class="string">"ms"</span>);
<a href=#406 id=406 data-nosnippet>406</a> test_timestamp_alias(<span class="string">"TimestampMicrosecond"</span>, <span class="string">"µs"</span>);
<a href=#407 id=407 data-nosnippet>407</a> test_timestamp_alias(<span class="string">"Timestamp_us"</span>, <span class="string">"µs"</span>);
<a href=#408 id=408 data-nosnippet>408</a> test_timestamp_alias(<span class="string">"TimestampNanosecond"</span>, <span class="string">"ns"</span>);
<a href=#409 id=409 data-nosnippet>409</a> test_timestamp_alias(<span class="string">"Timestamp_ns"</span>, <span class="string">"ns"</span>);
<a href=#410 id=410 data-nosnippet>410</a> <span class="comment">// Timestamp(precision)
<a href=#411 id=411 data-nosnippet>411</a> </span>test_timestamp_precision_type(<span class="number">0</span>, <span class="string">"s"</span>);
<a href=#412 id=412 data-nosnippet>412</a> test_timestamp_precision_type(<span class="number">3</span>, <span class="string">"ms"</span>);
<a href=#413 id=413 data-nosnippet>413</a> test_timestamp_precision_type(<span class="number">6</span>, <span class="string">"µs"</span>);
<a href=#414 id=414 data-nosnippet>414</a> test_timestamp_precision_type(<span class="number">9</span>, <span class="string">"ns"</span>);
<a href=#415 id=415 data-nosnippet>415</a> }
<a href=#416 id=416 data-nosnippet>416</a>
<a href=#417 id=417 data-nosnippet>417</a> <span class="attr">#[test]
<a href=#418 id=418 data-nosnippet>418</a> </span><span class="kw">fn </span>test_create_sql_with_type_alias() {
<a href=#419 id=419 data-nosnippet>419</a> <span class="kw">let </span>sql = <span class="string">r#"
<a href=#420 id=420 data-nosnippet>420</a>CREATE TABLE data_types (
<a href=#421 id=421 data-nosnippet>421</a> s string,
<a href=#422 id=422 data-nosnippet>422</a> tt tinytext,
<a href=#423 id=423 data-nosnippet>423</a> mt mediumtext,
<a href=#424 id=424 data-nosnippet>424</a> lt longtext,
<a href=#425 id=425 data-nosnippet>425</a> i2 int2,
<a href=#426 id=426 data-nosnippet>426</a> i4 int4,
<a href=#427 id=427 data-nosnippet>427</a> i8 int8,
<a href=#428 id=428 data-nosnippet>428</a> sint int16,
<a href=#429 id=429 data-nosnippet>429</a> i int32,
<a href=#430 id=430 data-nosnippet>430</a> bint int64,
<a href=#431 id=431 data-nosnippet>431</a> v varchar,
<a href=#432 id=432 data-nosnippet>432</a> f4 float4,
<a href=#433 id=433 data-nosnippet>433</a> f8 float8,
<a href=#434 id=434 data-nosnippet>434</a> f float32,
<a href=#435 id=435 data-nosnippet>435</a> d float64,
<a href=#436 id=436 data-nosnippet>436</a> b boolean,
<a href=#437 id=437 data-nosnippet>437</a> vb varbinary,
<a href=#438 id=438 data-nosnippet>438</a> dt date,
<a href=#439 id=439 data-nosnippet>439</a> dtt datetime,
<a href=#440 id=440 data-nosnippet>440</a> ts0 TimestampSecond,
<a href=#441 id=441 data-nosnippet>441</a> ts3 TimestampMillisecond,
<a href=#442 id=442 data-nosnippet>442</a> ts6 TimestampMicrosecond,
<a href=#443 id=443 data-nosnippet>443</a> ts9 TimestampNanosecond DEFAULT CURRENT_TIMESTAMP TIME INDEX,
<a href=#444 id=444 data-nosnippet>444</a> PRIMARY KEY(s));"#</span>;
<a href=#445 id=445 data-nosnippet>445</a>
<a href=#446 id=446 data-nosnippet>446</a> <span class="kw">let </span><span class="kw-2">mut </span>stmts =
<a href=#447 id=447 data-nosnippet>447</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GenericDialect {}, ParseOptions::default())
<a href=#448 id=448 data-nosnippet>448</a> .unwrap();
<a href=#449 id=449 data-nosnippet>449</a> transform_statements(<span class="kw-2">&amp;mut </span>stmts).unwrap();
<a href=#450 id=450 data-nosnippet>450</a>
<a href=#451 id=451 data-nosnippet>451</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#452 id=452 data-nosnippet>452</a> Statement::CreateTable(c) =&gt; {
<a href=#453 id=453 data-nosnippet>453</a> <span class="kw">let </span>expected = <span class="string">r#"CREATE TABLE data_types (
<a href=#454 id=454 data-nosnippet>454</a> s STRING,
<a href=#455 id=455 data-nosnippet>455</a> tt TINYTEXT,
<a href=#456 id=456 data-nosnippet>456</a> mt MEDIUMTEXT,
<a href=#457 id=457 data-nosnippet>457</a> lt LONGTEXT,
<a href=#458 id=458 data-nosnippet>458</a> i2 SMALLINT,
<a href=#459 id=459 data-nosnippet>459</a> i4 INT,
<a href=#460 id=460 data-nosnippet>460</a> i8 BIGINT,
<a href=#461 id=461 data-nosnippet>461</a> sint SMALLINT,
<a href=#462 id=462 data-nosnippet>462</a> i INT,
<a href=#463 id=463 data-nosnippet>463</a> bint BIGINT,
<a href=#464 id=464 data-nosnippet>464</a> v VARCHAR,
<a href=#465 id=465 data-nosnippet>465</a> f4 FLOAT,
<a href=#466 id=466 data-nosnippet>466</a> f8 DOUBLE,
<a href=#467 id=467 data-nosnippet>467</a> f FLOAT,
<a href=#468 id=468 data-nosnippet>468</a> d DOUBLE,
<a href=#469 id=469 data-nosnippet>469</a> b BOOLEAN,
<a href=#470 id=470 data-nosnippet>470</a> vb VARBINARY,
<a href=#471 id=471 data-nosnippet>471</a> dt DATE,
<a href=#472 id=472 data-nosnippet>472</a> dtt TIMESTAMP(6),
<a href=#473 id=473 data-nosnippet>473</a> ts0 TIMESTAMP(0),
<a href=#474 id=474 data-nosnippet>474</a> ts3 TIMESTAMP(3),
<a href=#475 id=475 data-nosnippet>475</a> ts6 TIMESTAMP(6),
<a href=#476 id=476 data-nosnippet>476</a> ts9 TIMESTAMP(9) DEFAULT CURRENT_TIMESTAMP NOT NULL,
<a href=#477 id=477 data-nosnippet>477</a> TIME INDEX (ts9),
<a href=#478 id=478 data-nosnippet>478</a> PRIMARY KEY (s)
<a href=#479 id=479 data-nosnippet>479</a>)
<a href=#480 id=480 data-nosnippet>480</a>ENGINE=mito
<a href=#481 id=481 data-nosnippet>481</a>"#</span>;
<a href=#482 id=482 data-nosnippet>482</a>
<a href=#483 id=483 data-nosnippet>483</a> <span class="macro">assert_eq!</span>(expected, c.to_string());
<a href=#484 id=484 data-nosnippet>484</a> }
<a href=#485 id=485 data-nosnippet>485</a> <span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
<a href=#486 id=486 data-nosnippet>486</a> }
<a href=#487 id=487 data-nosnippet>487</a> }
<a href=#488 id=488 data-nosnippet>488</a>}
</code></pre></div></section></main></body></html>
+170
View File
@@ -0,0 +1,170 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `src/sql/src/statements/truncate.rs`."><title>truncate.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-1ed95124.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="sql" data-themes="" data-resource-suffix="" data-rustdoc-version="1.98.1 (48a229cea 2026-09-01)" data-channel="1.98.1" data-search-js="search-9944d736.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-417ebf0a.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><h1><div class="sub-heading">sql/statements/</div>truncate.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="comment">// Copyright 2023 Greptime Team
<a href=#2 id=2 data-nosnippet>2</a>//
<a href=#3 id=3 data-nosnippet>3</a>// Licensed under the Apache License, Version 2.0 (the "License");
<a href=#4 id=4 data-nosnippet>4</a>// you may not use this file except in compliance with the License.
<a href=#5 id=5 data-nosnippet>5</a>// You may obtain a copy of the License at
<a href=#6 id=6 data-nosnippet>6</a>//
<a href=#7 id=7 data-nosnippet>7</a>// http://www.apache.org/licenses/LICENSE-2.0
<a href=#8 id=8 data-nosnippet>8</a>//
<a href=#9 id=9 data-nosnippet>9</a>// Unless required by applicable law or agreed to in writing, software
<a href=#10 id=10 data-nosnippet>10</a>// distributed under the License is distributed on an "AS IS" BASIS,
<a href=#11 id=11 data-nosnippet>11</a>// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<a href=#12 id=12 data-nosnippet>12</a>// See the License for the specific language governing permissions and
<a href=#13 id=13 data-nosnippet>13</a>// limitations under the License.
<a href=#14 id=14 data-nosnippet>14</a>
<a href=#15 id=15 data-nosnippet>15</a></span><span class="kw">use </span>std::fmt::Display;
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>itertools::Itertools;
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>serde::Serialize;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>sqlparser::ast::{ObjectName, Visit, VisitMut, Visitor, VisitorMut};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="doccomment">/// TRUNCATE TABLE statement.
<a href=#22 id=22 data-nosnippet>22</a></span><span class="attr">#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
<a href=#23 id=23 data-nosnippet>23</a></span><span class="kw">pub struct </span>TruncateTable {
<a href=#24 id=24 data-nosnippet>24</a> table_name: ObjectName,
<a href=#25 id=25 data-nosnippet>25</a> time_ranges: Vec&lt;(sqlparser::ast::Value, sqlparser::ast::Value)&gt;,
<a href=#26 id=26 data-nosnippet>26</a>}
<a href=#27 id=27 data-nosnippet>27</a>
<a href=#28 id=28 data-nosnippet>28</a><span class="kw">impl </span>Visit <span class="kw">for </span>TruncateTable {
<a href=#29 id=29 data-nosnippet>29</a> <span class="kw">fn </span>visit&lt;V: Visitor&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, visitor: <span class="kw-2">&amp;mut </span>V) -&gt; ::std::ops::ControlFlow&lt;V::Break&gt; {
<a href=#30 id=30 data-nosnippet>30</a> <span class="self">self</span>.table_name.visit(visitor)<span class="question-mark">?</span>;
<a href=#31 id=31 data-nosnippet>31</a> <span class="kw">for </span>(start, end) <span class="kw">in </span><span class="kw-2">&amp;</span><span class="self">self</span>.time_ranges {
<a href=#32 id=32 data-nosnippet>32</a> start.visit(visitor)<span class="question-mark">?</span>;
<a href=#33 id=33 data-nosnippet>33</a> end.visit(visitor)<span class="question-mark">?</span>;
<a href=#34 id=34 data-nosnippet>34</a> }
<a href=#35 id=35 data-nosnippet>35</a> ::std::ops::ControlFlow::Continue(())
<a href=#36 id=36 data-nosnippet>36</a> }
<a href=#37 id=37 data-nosnippet>37</a>}
<a href=#38 id=38 data-nosnippet>38</a>
<a href=#39 id=39 data-nosnippet>39</a><span class="kw">impl </span>VisitMut <span class="kw">for </span>TruncateTable {
<a href=#40 id=40 data-nosnippet>40</a> <span class="kw">fn </span>visit&lt;V: VisitorMut&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, visitor: <span class="kw-2">&amp;mut </span>V) -&gt; ::std::ops::ControlFlow&lt;V::Break&gt; {
<a href=#41 id=41 data-nosnippet>41</a> sqlparser::ast::VisitMut::visit(<span class="kw-2">&amp;mut </span><span class="self">self</span>.table_name, visitor)<span class="question-mark">?</span>;
<a href=#42 id=42 data-nosnippet>42</a> <span class="kw">for </span>(start, end) <span class="kw">in </span><span class="kw-2">&amp;mut </span><span class="self">self</span>.time_ranges {
<a href=#43 id=43 data-nosnippet>43</a> start.visit(visitor)<span class="question-mark">?</span>;
<a href=#44 id=44 data-nosnippet>44</a> end.visit(visitor)<span class="question-mark">?</span>;
<a href=#45 id=45 data-nosnippet>45</a> }
<a href=#46 id=46 data-nosnippet>46</a> ::std::ops::ControlFlow::Continue(())
<a href=#47 id=47 data-nosnippet>47</a> }
<a href=#48 id=48 data-nosnippet>48</a>}
<a href=#49 id=49 data-nosnippet>49</a>
<a href=#50 id=50 data-nosnippet>50</a><span class="kw">impl </span>TruncateTable {
<a href=#51 id=51 data-nosnippet>51</a> <span class="doccomment">/// Creates a statement for `TRUNCATE TABLE`
<a href=#52 id=52 data-nosnippet>52</a> </span><span class="kw">pub fn </span>new(table_name: ObjectName) -&gt; <span class="self">Self </span>{
<a href=#53 id=53 data-nosnippet>53</a> <span class="self">Self </span>{
<a href=#54 id=54 data-nosnippet>54</a> table_name,
<a href=#55 id=55 data-nosnippet>55</a> time_ranges: Vec::new(),
<a href=#56 id=56 data-nosnippet>56</a> }
<a href=#57 id=57 data-nosnippet>57</a> }
<a href=#58 id=58 data-nosnippet>58</a>
<a href=#59 id=59 data-nosnippet>59</a> <span class="doccomment">/// Creates a statement for `TRUNCATE TABLE RANGE`
<a href=#60 id=60 data-nosnippet>60</a> </span><span class="kw">pub fn </span>new_with_ranges(
<a href=#61 id=61 data-nosnippet>61</a> table_name: ObjectName,
<a href=#62 id=62 data-nosnippet>62</a> time_ranges: Vec&lt;(sqlparser::ast::Value, sqlparser::ast::Value)&gt;,
<a href=#63 id=63 data-nosnippet>63</a> ) -&gt; <span class="self">Self </span>{
<a href=#64 id=64 data-nosnippet>64</a> <span class="self">Self </span>{
<a href=#65 id=65 data-nosnippet>65</a> table_name,
<a href=#66 id=66 data-nosnippet>66</a> time_ranges,
<a href=#67 id=67 data-nosnippet>67</a> }
<a href=#68 id=68 data-nosnippet>68</a> }
<a href=#69 id=69 data-nosnippet>69</a>
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">pub fn </span>table_name(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ObjectName {
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw-2">&amp;</span><span class="self">self</span>.table_name
<a href=#72 id=72 data-nosnippet>72</a> }
<a href=#73 id=73 data-nosnippet>73</a>
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">pub fn </span>time_ranges(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[(sqlparser::ast::Value, sqlparser::ast::Value)] {
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw-2">&amp;</span><span class="self">self</span>.time_ranges
<a href=#76 id=76 data-nosnippet>76</a> }
<a href=#77 id=77 data-nosnippet>77</a>}
<a href=#78 id=78 data-nosnippet>78</a>
<a href=#79 id=79 data-nosnippet>79</a><span class="kw">impl </span>Display <span class="kw">for </span>TruncateTable {
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>std::fmt::Formatter&lt;<span class="lifetime">'_</span>&gt;) -&gt; std::fmt::Result {
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">let </span>table_name = <span class="self">self</span>.table_name();
<a href=#82 id=82 data-nosnippet>82</a> <span class="macro">write!</span>(f, <span class="string">r#"TRUNCATE TABLE {table_name}"#</span>)<span class="question-mark">?</span>;
<a href=#83 id=83 data-nosnippet>83</a> <span class="kw">if </span><span class="self">self</span>.time_ranges.is_empty() {
<a href=#84 id=84 data-nosnippet>84</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(());
<a href=#85 id=85 data-nosnippet>85</a> }
<a href=#86 id=86 data-nosnippet>86</a>
<a href=#87 id=87 data-nosnippet>87</a> <span class="macro">write!</span>(f, <span class="string">" FILE RANGE "</span>)<span class="question-mark">?</span>;
<a href=#88 id=88 data-nosnippet>88</a> <span class="macro">write!</span>(
<a href=#89 id=89 data-nosnippet>89</a> f,
<a href=#90 id=90 data-nosnippet>90</a> <span class="string">"{}"</span>,
<a href=#91 id=91 data-nosnippet>91</a> <span class="self">self</span>.time_ranges
<a href=#92 id=92 data-nosnippet>92</a> .iter()
<a href=#93 id=93 data-nosnippet>93</a> .map(|(start, end)| <span class="macro">format!</span>(<span class="string">"({}, {})"</span>, start, end))
<a href=#94 id=94 data-nosnippet>94</a> .join(<span class="string">", "</span>)
<a href=#95 id=95 data-nosnippet>95</a> )
<a href=#96 id=96 data-nosnippet>96</a> }
<a href=#97 id=97 data-nosnippet>97</a>}
<a href=#98 id=98 data-nosnippet>98</a>
<a href=#99 id=99 data-nosnippet>99</a><span class="attr">#[cfg(test)]
<a href=#100 id=100 data-nosnippet>100</a></span><span class="kw">mod </span>tests {
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">use </span>std::assert_matches;
<a href=#102 id=102 data-nosnippet>102</a>
<a href=#103 id=103 data-nosnippet>103</a> <span class="kw">use </span><span class="kw">crate</span>::dialect::GreptimeDbDialect;
<a href=#104 id=104 data-nosnippet>104</a> <span class="kw">use </span><span class="kw">crate</span>::parser::{ParseOptions, ParserContext};
<a href=#105 id=105 data-nosnippet>105</a> <span class="kw">use </span><span class="kw">crate</span>::statements::statement::Statement;
<a href=#106 id=106 data-nosnippet>106</a>
<a href=#107 id=107 data-nosnippet>107</a> <span class="attr">#[test]
<a href=#108 id=108 data-nosnippet>108</a> </span><span class="kw">fn </span>test_display_for_truncate_table() {
<a href=#109 id=109 data-nosnippet>109</a> <span class="kw">let </span>sql = <span class="string">r"truncate table t1;"</span>;
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#111 id=111 data-nosnippet>111</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#112 id=112 data-nosnippet>112</a> .unwrap();
<a href=#113 id=113 data-nosnippet>113</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#114 id=114 data-nosnippet>114</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::TruncateTable { .. });
<a href=#115 id=115 data-nosnippet>115</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#116 id=116 data-nosnippet>116</a> Statement::TruncateTable(trunc) =&gt; {
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, trunc);
<a href=#118 id=118 data-nosnippet>118</a> <span class="macro">assert_eq!</span>(
<a href=#119 id=119 data-nosnippet>119</a> <span class="string">r#"
<a href=#120 id=120 data-nosnippet>120</a>TRUNCATE TABLE t1"#</span>,
<a href=#121 id=121 data-nosnippet>121</a> <span class="kw-2">&amp;</span>new_sql
<a href=#122 id=122 data-nosnippet>122</a> );
<a href=#123 id=123 data-nosnippet>123</a> }
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">_ </span>=&gt; {
<a href=#125 id=125 data-nosnippet>125</a> <span class="macro">unreachable!</span>();
<a href=#126 id=126 data-nosnippet>126</a> }
<a href=#127 id=127 data-nosnippet>127</a> }
<a href=#128 id=128 data-nosnippet>128</a>
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">let </span>sql = <span class="string">r"truncate table t1 file range (1,2);"</span>;
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#131 id=131 data-nosnippet>131</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#132 id=132 data-nosnippet>132</a> .unwrap();
<a href=#133 id=133 data-nosnippet>133</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#134 id=134 data-nosnippet>134</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::TruncateTable { .. });
<a href=#135 id=135 data-nosnippet>135</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#136 id=136 data-nosnippet>136</a> Statement::TruncateTable(trunc) =&gt; {
<a href=#137 id=137 data-nosnippet>137</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, trunc);
<a href=#138 id=138 data-nosnippet>138</a> <span class="macro">assert_eq!</span>(
<a href=#139 id=139 data-nosnippet>139</a> <span class="string">r#"
<a href=#140 id=140 data-nosnippet>140</a>TRUNCATE TABLE t1 FILE RANGE (1, 2)"#</span>,
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw-2">&amp;</span>new_sql
<a href=#142 id=142 data-nosnippet>142</a> );
<a href=#143 id=143 data-nosnippet>143</a> }
<a href=#144 id=144 data-nosnippet>144</a> <span class="kw">_ </span>=&gt; {
<a href=#145 id=145 data-nosnippet>145</a> <span class="macro">unreachable!</span>();
<a href=#146 id=146 data-nosnippet>146</a> }
<a href=#147 id=147 data-nosnippet>147</a> }
<a href=#148 id=148 data-nosnippet>148</a>
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw">let </span>sql = <span class="string">r"truncate table t1 file range (1,2), (3,4);"</span>;
<a href=#150 id=150 data-nosnippet>150</a> <span class="kw">let </span>stmts: Vec&lt;Statement&gt; =
<a href=#151 id=151 data-nosnippet>151</a> ParserContext::create_with_dialect(sql, <span class="kw-2">&amp;</span>GreptimeDbDialect {}, ParseOptions::default())
<a href=#152 id=152 data-nosnippet>152</a> .unwrap();
<a href=#153 id=153 data-nosnippet>153</a> <span class="macro">assert_eq!</span>(<span class="number">1</span>, stmts.len());
<a href=#154 id=154 data-nosnippet>154</a> <span class="macro">assert_matches!</span>(<span class="kw-2">&amp;</span>stmts[<span class="number">0</span>], Statement::TruncateTable { .. });
<a href=#155 id=155 data-nosnippet>155</a> <span class="kw">match </span><span class="kw-2">&amp;</span>stmts[<span class="number">0</span>] {
<a href=#156 id=156 data-nosnippet>156</a> Statement::TruncateTable(trunc) =&gt; {
<a href=#157 id=157 data-nosnippet>157</a> <span class="kw">let </span>new_sql = <span class="macro">format!</span>(<span class="string">"\n{}"</span>, trunc);
<a href=#158 id=158 data-nosnippet>158</a> <span class="macro">assert_eq!</span>(
<a href=#159 id=159 data-nosnippet>159</a> <span class="string">r#"
<a href=#160 id=160 data-nosnippet>160</a>TRUNCATE TABLE t1 FILE RANGE (1, 2), (3, 4)"#</span>,
<a href=#161 id=161 data-nosnippet>161</a> <span class="kw-2">&amp;</span>new_sql
<a href=#162 id=162 data-nosnippet>162</a> );
<a href=#163 id=163 data-nosnippet>163</a> }
<a href=#164 id=164 data-nosnippet>164</a> <span class="kw">_ </span>=&gt; {
<a href=#165 id=165 data-nosnippet>165</a> <span class="macro">unreachable!</span>();
<a href=#166 id=166 data-nosnippet>166</a> }
<a href=#167 id=167 data-nosnippet>167</a> }
<a href=#168 id=168 data-nosnippet>168</a> }
<a href=#169 id=169 data-nosnippet>169</a>}
</code></pre></div></section></main></body></html>
+1080
View File
File diff suppressed because it is too large Load Diff