Skip to main content

polyglot_sql/dialects/
solr.rs

1//! Apache Solr SQL Dialect
2//!
3//! Solr-specific SQL dialect based on sqlglot patterns.
4//! Reference: https://solr.apache.org/guide/solr/latest/query-guide/sql-query.html
5//!
6//! Key characteristics:
7//! - Case insensitive normalization
8//! - Uses backticks for identifiers
9//! - Single quotes for strings only
10//! - Note: `||` is OR in Solr (not string concatenation)
11//! - Does not support SEMI/ANTI joins
12
13use super::{DialectImpl, DialectType};
14use crate::error::Result;
15use crate::expressions::{BinaryOp, Expression};
16#[cfg(feature = "generate")]
17use crate::generator::GeneratorConfig;
18use crate::tokens::TokenizerConfig;
19
20/// Apache Solr dialect
21pub struct SolrDialect;
22
23impl DialectImpl for SolrDialect {
24    fn dialect_type(&self) -> DialectType {
25        DialectType::Solr
26    }
27
28    fn tokenizer_config(&self) -> TokenizerConfig {
29        let mut config = TokenizerConfig::default();
30        // Solr uses backticks for identifiers
31        config.identifiers.insert('`', '`');
32        // Single quotes only for strings
33        // Note: Default tokenizer already handles single quotes for strings
34        config
35    }
36
37    #[cfg(feature = "generate")]
38
39    fn generator_config(&self) -> GeneratorConfig {
40        use crate::generator::IdentifierQuoteStyle;
41        GeneratorConfig {
42            identifier_quote: '`',
43            identifier_quote_style: IdentifierQuoteStyle::BACKTICK,
44            dialect: Some(DialectType::Solr),
45            ..Default::default()
46        }
47    }
48
49    #[cfg(feature = "transpile")]
50
51    fn transform_expr(&self, expr: Expression) -> Result<Expression> {
52        // Solr has limited SQL support
53        // In Solr, || is OR, not string concatenation (DPIPE_IS_STRING_CONCAT = False in sqlglot)
54        match expr {
55            Expression::DPipe(dpipe) => {
56                // Transform DPipe (||) to Or
57                let left = self.transform_expr(*dpipe.this)?;
58                let right = self.transform_expr(*dpipe.expression)?;
59                Ok(Expression::Or(Box::new(BinaryOp::new(left, right))))
60            }
61            _ => Ok(expr),
62        }
63    }
64}