You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2022/11/03 22:43:40 UTC

[GitHub] [arrow-datafusion] andygrove opened a new pull request, #4102: Parse SQL numeric literals as decimal for compliance with ANSI SQL

andygrove opened a new pull request, #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102

   # Which issue does this PR close?
   
   <!--
   We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123.
   -->
   
   Closes https://github.com/apache/arrow-datafusion/issues/4072
   
   Partially fixes https://github.com/apache/arrow-datafusion/issues/4024 and https://github.com/apache/arrow-datafusion/issues/192
   
   # Rationale for this change
   
   <!--
    Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed.
    Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes.  
   -->
   
   Main motivation is to get benchmark query q6 returning the correct results but this is also the correct behavior for SQL
   
   # What changes are included in this PR?
   
   <!--
   There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR.
   -->
   
   # Are there any user-facing changes?
   
   <!--
   If there are user-facing changes then we may require documentation to be updated before approving the PR.
   -->
   
   <!--
   If there are any breaking changes to public APIs, please add the `api change` label.
   -->


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#issuecomment-1315999127

   🎉 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1014482609


##########
datafusion/sql/src/planner.rs:
##########
@@ -2671,6 +2694,49 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
             Ok(lit(ScalarValue::new_list(Some(values), data_type)))
         }
     }
+
+    /// Parse number in sql string, convert to Expr::Literal
+    fn parse_sql_number(&self, n: &str) -> Result<Expr> {
+        if let Some(_) = n.find('E') {
+            // not implemented yet
+            // https://github.com/apache/arrow-datafusion/issues/3448
+            Err(DataFusionError::NotImplemented(
+                "sql numeric literals in scientific notation are not supported"
+                    .to_string(),
+            ))
+        } else if let Ok(n) = n.parse::<i64>() {
+            Ok(lit(n))
+        } else if self.options.parse_float_as_decimal {
+            if let Some(i) = n.find('.') {
+                let p = n.len() - 1;
+                let s = n.len() - i - 1;
+                let str = n.replace('.', "");
+                let n = str.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal. Input token: {}",
+                        str, n
+                    )))
+                })?;
+                Ok(Expr::Literal(ScalarValue::Decimal128(
+                    Some(n),
+                    p as u8,
+                    s as u8,
+                )))
+            } else {
+                let number = n.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal",
+                        n
+                    )))
+                })?;
+                Ok(Expr::Literal(ScalarValue::Decimal128(Some(number), 38, 0)))

Review Comment:
   Can we get the minimum precision to handle this number?
   
   
   ```
   scala> sql("select 10000000000000000000")
   res10: org.apache.spark.sql.DataFrame = [10000000000000000000: decimal(20,0)]
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] andygrove commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
andygrove commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1022173833


##########
datafusion/sql/src/planner.rs:
##########
@@ -2671,6 +2694,49 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
             Ok(lit(ScalarValue::new_list(Some(values), data_type)))
         }
     }
+
+    /// Parse number in sql string, convert to Expr::Literal
+    fn parse_sql_number(&self, n: &str) -> Result<Expr> {
+        if let Some(_) = n.find('E') {
+            // not implemented yet
+            // https://github.com/apache/arrow-datafusion/issues/3448
+            Err(DataFusionError::NotImplemented(
+                "sql numeric literals in scientific notation are not supported"
+                    .to_string(),
+            ))
+        } else if let Ok(n) = n.parse::<i64>() {
+            Ok(lit(n))
+        } else if self.options.parse_float_as_decimal {
+            if let Some(i) = n.find('.') {
+                let p = n.len() - 1;
+                let s = n.len() - i - 1;
+                let str = n.replace('.', "");
+                let n = str.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal. Input token: {}",
+                        str, n
+                    )))
+                })?;
+                Ok(Expr::Literal(ScalarValue::Decimal128(
+                    Some(n),
+                    p as u8,
+                    s as u8,
+                )))
+            } else {
+                let number = n.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal",
+                        n
+                    )))
+                })?;
+                Ok(Expr::Literal(ScalarValue::Decimal128(Some(number), 38, 0)))

Review Comment:
   @viirya Could you take another look when you have time?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1013529771


##########
datafusion/sql/src/planner.rs:
##########
@@ -2671,6 +2694,49 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
             Ok(lit(ScalarValue::new_list(Some(values), data_type)))
         }
     }
+
+    /// Parse number in sql string, convert to Expr::Literal
+    fn parse_sql_number(&self, n: &str) -> Result<Expr> {
+        if let Some(_) = n.find('E') {
+            // not implemented yet
+            // https://github.com/apache/arrow-datafusion/issues/3448
+            Err(DataFusionError::NotImplemented(
+                "sql numeric literals in scientific notation are not supported"
+                    .to_string(),
+            ))
+        } else if let Ok(n) = n.parse::<i64>() {
+            Ok(lit(n))
+        } else if self.options.parse_float_as_decimal {
+            if let Some(i) = n.find('.') {
+                let p = n.len() - 1;
+                let s = n.len() - i - 1;
+                let str = n.replace('.', "");
+                let n = str.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal",
+                        str

Review Comment:
   Maybe good to print out original string too, i.e.,
   
   ```suggestion
                           "Cannot parse {} as i128 when building decimal. Input token: {}",
                           str, n
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] ursabot commented on pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
ursabot commented on PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#issuecomment-1315985455

   Benchmark runs are scheduled for baseline = ebb24c5bf46f2af362aebffba2012875b328e799 and contender = 406c1087bc16f8d2a49e5a9b05d2a0e1b67f7aa5. 406c1087bc16f8d2a49e5a9b05d2a0e1b67f7aa5 is a master commit associated with this PR. Results will be available as each benchmark for each run completes.
   Conbench compare runs links:
   [Skipped :warning: Benchmarking of arrow-datafusion-commits is not supported on ec2-t3-xlarge-us-east-2] [ec2-t3-xlarge-us-east-2](https://conbench.ursa.dev/compare/runs/3e53019be38b4bb7a6b601b69ef5165b...86c7085020b546399ec515aa74b5ce49/)
   [Skipped :warning: Benchmarking of arrow-datafusion-commits is not supported on test-mac-arm] [test-mac-arm](https://conbench.ursa.dev/compare/runs/fffdb6d85d6c4d9989c110dc0d7e7a28...3e4c00c0f86b412a8b3b8de1879dddbf/)
   [Skipped :warning: Benchmarking of arrow-datafusion-commits is not supported on ursa-i9-9960x] [ursa-i9-9960x](https://conbench.ursa.dev/compare/runs/14253d3a91ca4db197f2b14145a584be...74ad3596b74f468698eaa88b01401ff7/)
   [Skipped :warning: Benchmarking of arrow-datafusion-commits is not supported on ursa-thinkcentre-m75q] [ursa-thinkcentre-m75q](https://conbench.ursa.dev/compare/runs/5bebc271bbc04954963d750109086730...d5e1653429e448d09c7c7fb1bc04b0c8/)
   Buildkite builds:
   Supported benchmarks:
   ec2-t3-xlarge-us-east-2: Supported benchmark langs: Python, R. Runs only benchmarks with cloud = True
   test-mac-arm: Supported benchmark langs: C++, Python, R
   ursa-i9-9960x: Supported benchmark langs: Python, R, JavaScript
   ursa-thinkcentre-m75q: Supported benchmark langs: C++, Java
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] andygrove merged pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
andygrove merged PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1013530934


##########
datafusion/sql/src/planner.rs:
##########
@@ -2907,28 +2973,26 @@ pub fn convert_data_type(sql_type: &SQLDataType) -> Result<DataType> {
     }
 }
 
-// Parse number in sql string, convert to Expr::Literal
-fn parse_sql_number(n: &str) -> Result<Expr> {
-    // parse first as i64
-    n.parse::<i64>()
-        .map(lit)
-        // if parsing as i64 fails try f64
-        .or_else(|_| n.parse::<f64>().map(lit))
-        .map_err(|_| {
-            DataFusionError::from(ParserError(format!(
-                "Cannot parse {} as i64 or f64",
-                n
-            )))
-        })
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
     use datafusion_common::assert_contains;
     use sqlparser::dialect::{Dialect, GenericDialect, HiveDialect, MySqlDialect};
     use std::any::Any;
 
+    #[test]
+    fn parse_decimals() {
+        let options = ParserOptions {
+            parse_float_as_decimal: true,
+        };
+        quick_test_with_options(
+            "SELECT 1, 1.0, 0.1, .1, 12.34",
+            "Projection: Int64(1), Decimal128(Some(10),2,1), Decimal128(Some(1),2,1), Decimal128(Some(1),1,1), Decimal128(Some(1234),4,2)\

Review Comment:
   `0.1` should be Decimal(1, 1), I think.
   
   ```
   scala> sql("select 0.1")
   res0: org.apache.spark.sql.DataFrame = [0.1: decimal(1,1)]
   ```
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1022176824


##########
datafusion/sql/src/planner.rs:
##########
@@ -2671,6 +2694,49 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
             Ok(lit(ScalarValue::new_list(Some(values), data_type)))
         }
     }
+
+    /// Parse number in sql string, convert to Expr::Literal
+    fn parse_sql_number(&self, n: &str) -> Result<Expr> {
+        if let Some(_) = n.find('E') {
+            // not implemented yet
+            // https://github.com/apache/arrow-datafusion/issues/3448
+            Err(DataFusionError::NotImplemented(
+                "sql numeric literals in scientific notation are not supported"
+                    .to_string(),
+            ))
+        } else if let Ok(n) = n.parse::<i64>() {
+            Ok(lit(n))
+        } else if self.options.parse_float_as_decimal {
+            if let Some(i) = n.find('.') {
+                let p = n.len() - 1;
+                let s = n.len() - i - 1;
+                let str = n.replace('.', "");
+                let n = str.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal. Input token: {}",
+                        str, n
+                    )))
+                })?;
+                Ok(Expr::Literal(ScalarValue::Decimal128(
+                    Some(n),
+                    p as u8,
+                    s as u8,
+                )))
+            } else {
+                let number = n.parse::<i128>().map_err(|_| {
+                    DataFusionError::from(ParserError(format!(
+                        "Cannot parse {} as i128 when building decimal",
+                        n
+                    )))
+                })?;
+                Ok(Expr::Literal(ScalarValue::Decimal128(Some(number), 38, 0)))

Review Comment:
   I'd love to do it. Let me take another look.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1022184509


##########
datafusion/sql/src/planner.rs:
##########
@@ -2919,19 +2987,103 @@ fn extract_possible_join_keys(
     }
 }
 
-// Parse number in sql string, convert to Expr::Literal
-fn parse_sql_number(n: &str) -> Result<Expr> {
-    // parse first as i64
-    n.parse::<i64>()
-        .map(lit)
-        // if parsing as i64 fails try f64
-        .or_else(|_| n.parse::<f64>().map(lit))
-        .map_err(|_| {
-            DataFusionError::from(ParserError(format!(
-                "Cannot parse {} as i64 or f64",
-                n
-            )))
-        })
+/// Convert SQL simple data type to relational representation of data type
+pub fn convert_simple_data_type(sql_type: &SQLDataType) -> Result<DataType> {
+    match sql_type {
+        SQLDataType::Boolean => Ok(DataType::Boolean),
+        SQLDataType::TinyInt(_) => Ok(DataType::Int8),
+        SQLDataType::SmallInt(_) => Ok(DataType::Int16),
+        SQLDataType::Int(_) | SQLDataType::Integer(_) => Ok(DataType::Int32),
+        SQLDataType::BigInt(_) => Ok(DataType::Int64),
+        SQLDataType::UnsignedTinyInt(_) => Ok(DataType::UInt8),
+        SQLDataType::UnsignedSmallInt(_) => Ok(DataType::UInt16),
+        SQLDataType::UnsignedInt(_) | SQLDataType::UnsignedInteger(_) => {
+            Ok(DataType::UInt32)
+        }
+        SQLDataType::UnsignedBigInt(_) => Ok(DataType::UInt64),
+        SQLDataType::Float(_) => Ok(DataType::Float32),
+        SQLDataType::Real => Ok(DataType::Float32),
+        SQLDataType::Double | SQLDataType::DoublePrecision => Ok(DataType::Float64),
+        SQLDataType::Char(_)
+        | SQLDataType::Varchar(_)
+        | SQLDataType::Text
+        | SQLDataType::String => Ok(DataType::Utf8),
+        SQLDataType::Timestamp(tz_info) => {
+            let tz = if matches!(tz_info, TimezoneInfo::Tz)
+                || matches!(tz_info, TimezoneInfo::WithTimeZone)
+            {
+                Some("UTC".to_string())
+            } else {
+                None
+            };
+            Ok(DataType::Timestamp(TimeUnit::Nanosecond, tz))
+        }
+        SQLDataType::Date => Ok(DataType::Date32),
+        SQLDataType::Time(tz_info) => {
+            if matches!(tz_info, TimezoneInfo::None)
+                || matches!(tz_info, TimezoneInfo::WithoutTimeZone)
+            {
+                Ok(DataType::Time64(TimeUnit::Nanosecond))
+            } else {
+                // We dont support TIMETZ and TIME WITH TIME ZONE for now
+                Err(DataFusionError::NotImplemented(format!(
+                    "Unsupported SQL type {:?}",
+                    sql_type
+                )))
+            }
+        }
+        SQLDataType::Decimal(exact_number_info) => {
+            let (precision, scale) = match *exact_number_info {
+                ExactNumberInfo::None => (None, None),
+                ExactNumberInfo::Precision(precision) => (Some(precision), None),
+                ExactNumberInfo::PrecisionAndScale(precision, scale) => {
+                    (Some(precision), Some(scale))
+                }
+            };
+            make_decimal_type(precision, scale)
+        }
+        SQLDataType::Bytea => Ok(DataType::Binary),
+        // Explicitly list all other types so that if sqlparser
+        // adds/changes the `SQLDataType` the compiler will tell us on upgrade
+        // and avoid bugs like https://github.com/apache/arrow-datafusion/issues/3059
+        SQLDataType::Nvarchar(_)
+        | SQLDataType::Uuid
+        | SQLDataType::Binary(_)
+        | SQLDataType::Varbinary(_)
+        | SQLDataType::Blob(_)
+        | SQLDataType::Datetime
+        | SQLDataType::Interval
+        | SQLDataType::Regclass
+        | SQLDataType::Custom(_)
+        | SQLDataType::Array(_)
+        | SQLDataType::Enum(_)
+        | SQLDataType::Set(_)
+        | SQLDataType::MediumInt(_)
+        | SQLDataType::UnsignedMediumInt(_)
+        | SQLDataType::Character(_)
+        | SQLDataType::CharacterVarying(_)
+        | SQLDataType::CharVarying(_)
+        | SQLDataType::CharacterLargeObject(_)
+        | SQLDataType::CharLargeObject(_)
+        | SQLDataType::Clob(_) => Err(DataFusionError::NotImplemented(format!(
+            "Unsupported SQL type {:?}",
+            sql_type
+        ))),
+    }
+}
+
+/// Convert SQL data type to relational representation of data type
+pub fn convert_data_type(sql_type: &SQLDataType) -> Result<DataType> {

Review Comment:
   Not sure why this change adds this and `convert_simple_data_type`. Otherwise other change looks good to me.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] viirya commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
viirya commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1022183556


##########
datafusion/sql/src/planner.rs:
##########
@@ -2919,19 +2987,103 @@ fn extract_possible_join_keys(
     }
 }
 
-// Parse number in sql string, convert to Expr::Literal
-fn parse_sql_number(n: &str) -> Result<Expr> {
-    // parse first as i64
-    n.parse::<i64>()
-        .map(lit)
-        // if parsing as i64 fails try f64
-        .or_else(|_| n.parse::<f64>().map(lit))
-        .map_err(|_| {
-            DataFusionError::from(ParserError(format!(
-                "Cannot parse {} as i64 or f64",
-                n
-            )))
-        })
+/// Convert SQL simple data type to relational representation of data type
+pub fn convert_simple_data_type(sql_type: &SQLDataType) -> Result<DataType> {
+    match sql_type {
+        SQLDataType::Boolean => Ok(DataType::Boolean),
+        SQLDataType::TinyInt(_) => Ok(DataType::Int8),
+        SQLDataType::SmallInt(_) => Ok(DataType::Int16),
+        SQLDataType::Int(_) | SQLDataType::Integer(_) => Ok(DataType::Int32),
+        SQLDataType::BigInt(_) => Ok(DataType::Int64),
+        SQLDataType::UnsignedTinyInt(_) => Ok(DataType::UInt8),
+        SQLDataType::UnsignedSmallInt(_) => Ok(DataType::UInt16),
+        SQLDataType::UnsignedInt(_) | SQLDataType::UnsignedInteger(_) => {
+            Ok(DataType::UInt32)
+        }
+        SQLDataType::UnsignedBigInt(_) => Ok(DataType::UInt64),
+        SQLDataType::Float(_) => Ok(DataType::Float32),
+        SQLDataType::Real => Ok(DataType::Float32),
+        SQLDataType::Double | SQLDataType::DoublePrecision => Ok(DataType::Float64),
+        SQLDataType::Char(_)
+        | SQLDataType::Varchar(_)
+        | SQLDataType::Text
+        | SQLDataType::String => Ok(DataType::Utf8),
+        SQLDataType::Timestamp(tz_info) => {
+            let tz = if matches!(tz_info, TimezoneInfo::Tz)
+                || matches!(tz_info, TimezoneInfo::WithTimeZone)
+            {
+                Some("UTC".to_string())
+            } else {
+                None
+            };
+            Ok(DataType::Timestamp(TimeUnit::Nanosecond, tz))
+        }
+        SQLDataType::Date => Ok(DataType::Date32),
+        SQLDataType::Time(tz_info) => {
+            if matches!(tz_info, TimezoneInfo::None)
+                || matches!(tz_info, TimezoneInfo::WithoutTimeZone)
+            {
+                Ok(DataType::Time64(TimeUnit::Nanosecond))
+            } else {
+                // We dont support TIMETZ and TIME WITH TIME ZONE for now
+                Err(DataFusionError::NotImplemented(format!(
+                    "Unsupported SQL type {:?}",
+                    sql_type
+                )))
+            }
+        }
+        SQLDataType::Decimal(exact_number_info) => {
+            let (precision, scale) = match *exact_number_info {
+                ExactNumberInfo::None => (None, None),
+                ExactNumberInfo::Precision(precision) => (Some(precision), None),
+                ExactNumberInfo::PrecisionAndScale(precision, scale) => {
+                    (Some(precision), Some(scale))
+                }
+            };
+            make_decimal_type(precision, scale)
+        }
+        SQLDataType::Bytea => Ok(DataType::Binary),
+        // Explicitly list all other types so that if sqlparser
+        // adds/changes the `SQLDataType` the compiler will tell us on upgrade
+        // and avoid bugs like https://github.com/apache/arrow-datafusion/issues/3059
+        SQLDataType::Nvarchar(_)
+        | SQLDataType::Uuid
+        | SQLDataType::Binary(_)
+        | SQLDataType::Varbinary(_)
+        | SQLDataType::Blob(_)
+        | SQLDataType::Datetime
+        | SQLDataType::Interval
+        | SQLDataType::Regclass
+        | SQLDataType::Custom(_)
+        | SQLDataType::Array(_)
+        | SQLDataType::Enum(_)
+        | SQLDataType::Set(_)
+        | SQLDataType::MediumInt(_)
+        | SQLDataType::UnsignedMediumInt(_)
+        | SQLDataType::Character(_)
+        | SQLDataType::CharacterVarying(_)
+        | SQLDataType::CharVarying(_)
+        | SQLDataType::CharacterLargeObject(_)
+        | SQLDataType::CharLargeObject(_)
+        | SQLDataType::Clob(_) => Err(DataFusionError::NotImplemented(format!(
+            "Unsupported SQL type {:?}",
+            sql_type
+        ))),
+    }
+}
+
+/// Convert SQL data type to relational representation of data type
+pub fn convert_data_type(sql_type: &SQLDataType) -> Result<DataType> {

Review Comment:
   Is this committed in accidentally? 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] andygrove commented on pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
andygrove commented on PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#issuecomment-1302801511

   @kmitchener @viirya @Dandandan PTAL


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] liukun4515 commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
liukun4515 commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1013579683


##########
datafusion/sql/src/planner.rs:
##########
@@ -2907,28 +2973,26 @@ pub fn convert_data_type(sql_type: &SQLDataType) -> Result<DataType> {
     }
 }
 
-// Parse number in sql string, convert to Expr::Literal
-fn parse_sql_number(n: &str) -> Result<Expr> {
-    // parse first as i64
-    n.parse::<i64>()
-        .map(lit)
-        // if parsing as i64 fails try f64
-        .or_else(|_| n.parse::<f64>().map(lit))
-        .map_err(|_| {
-            DataFusionError::from(ParserError(format!(
-                "Cannot parse {} as i64 or f64",
-                n
-            )))
-        })
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
     use datafusion_common::assert_contains;
     use sqlparser::dialect::{Dialect, GenericDialect, HiveDialect, MySqlDialect};
     use std::any::Any;
 
+    #[test]
+    fn parse_decimals() {
+        let options = ParserOptions {
+            parse_float_as_decimal: true,
+        };
+        quick_test_with_options(
+            "SELECT 1, 1.0, 0.1, .1, 12.34",
+            "Projection: Int64(1), Decimal128(Some(10),2,1), Decimal128(Some(1),2,1), Decimal128(Some(1),1,1), Decimal128(Some(1234),4,2)\

Review Comment:
   we should try to use the min precision to represent the value in the decimal literal



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] liukun4515 commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
liukun4515 commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1013579030


##########
datafusion/sql/src/planner.rs:
##########
@@ -2907,28 +2973,26 @@ pub fn convert_data_type(sql_type: &SQLDataType) -> Result<DataType> {
     }
 }
 
-// Parse number in sql string, convert to Expr::Literal
-fn parse_sql_number(n: &str) -> Result<Expr> {
-    // parse first as i64
-    n.parse::<i64>()
-        .map(lit)
-        // if parsing as i64 fails try f64
-        .or_else(|_| n.parse::<f64>().map(lit))
-        .map_err(|_| {
-            DataFusionError::from(ParserError(format!(
-                "Cannot parse {} as i64 or f64",
-                n
-            )))
-        })
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
     use datafusion_common::assert_contains;
     use sqlparser::dialect::{Dialect, GenericDialect, HiveDialect, MySqlDialect};
     use std::any::Any;
 
+    #[test]
+    fn parse_decimals() {
+        let options = ParserOptions {
+            parse_float_as_decimal: true,
+        };
+        quick_test_with_options(
+            "SELECT 1, 1.0, 0.1, .1, 12.34",
+            "Projection: Int64(1), Decimal128(Some(10),2,1), Decimal128(Some(1),2,1), Decimal128(Some(1),1,1), Decimal128(Some(1234),4,2)\

Review Comment:
   agree



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-datafusion] andygrove commented on a diff in pull request #4102: Add parser option for parsing SQL numeric literals as decimal

Posted by GitBox <gi...@apache.org>.
andygrove commented on code in PR #4102:
URL: https://github.com/apache/arrow-datafusion/pull/4102#discussion_r1022958637


##########
datafusion/sql/src/planner.rs:
##########
@@ -2919,19 +2987,103 @@ fn extract_possible_join_keys(
     }
 }
 
-// Parse number in sql string, convert to Expr::Literal
-fn parse_sql_number(n: &str) -> Result<Expr> {
-    // parse first as i64
-    n.parse::<i64>()
-        .map(lit)
-        // if parsing as i64 fails try f64
-        .or_else(|_| n.parse::<f64>().map(lit))
-        .map_err(|_| {
-            DataFusionError::from(ParserError(format!(
-                "Cannot parse {} as i64 or f64",
-                n
-            )))
-        })
+/// Convert SQL simple data type to relational representation of data type
+pub fn convert_simple_data_type(sql_type: &SQLDataType) -> Result<DataType> {
+    match sql_type {
+        SQLDataType::Boolean => Ok(DataType::Boolean),
+        SQLDataType::TinyInt(_) => Ok(DataType::Int8),
+        SQLDataType::SmallInt(_) => Ok(DataType::Int16),
+        SQLDataType::Int(_) | SQLDataType::Integer(_) => Ok(DataType::Int32),
+        SQLDataType::BigInt(_) => Ok(DataType::Int64),
+        SQLDataType::UnsignedTinyInt(_) => Ok(DataType::UInt8),
+        SQLDataType::UnsignedSmallInt(_) => Ok(DataType::UInt16),
+        SQLDataType::UnsignedInt(_) | SQLDataType::UnsignedInteger(_) => {
+            Ok(DataType::UInt32)
+        }
+        SQLDataType::UnsignedBigInt(_) => Ok(DataType::UInt64),
+        SQLDataType::Float(_) => Ok(DataType::Float32),
+        SQLDataType::Real => Ok(DataType::Float32),
+        SQLDataType::Double | SQLDataType::DoublePrecision => Ok(DataType::Float64),
+        SQLDataType::Char(_)
+        | SQLDataType::Varchar(_)
+        | SQLDataType::Text
+        | SQLDataType::String => Ok(DataType::Utf8),
+        SQLDataType::Timestamp(tz_info) => {
+            let tz = if matches!(tz_info, TimezoneInfo::Tz)
+                || matches!(tz_info, TimezoneInfo::WithTimeZone)
+            {
+                Some("UTC".to_string())
+            } else {
+                None
+            };
+            Ok(DataType::Timestamp(TimeUnit::Nanosecond, tz))
+        }
+        SQLDataType::Date => Ok(DataType::Date32),
+        SQLDataType::Time(tz_info) => {
+            if matches!(tz_info, TimezoneInfo::None)
+                || matches!(tz_info, TimezoneInfo::WithoutTimeZone)
+            {
+                Ok(DataType::Time64(TimeUnit::Nanosecond))
+            } else {
+                // We dont support TIMETZ and TIME WITH TIME ZONE for now
+                Err(DataFusionError::NotImplemented(format!(
+                    "Unsupported SQL type {:?}",
+                    sql_type
+                )))
+            }
+        }
+        SQLDataType::Decimal(exact_number_info) => {
+            let (precision, scale) = match *exact_number_info {
+                ExactNumberInfo::None => (None, None),
+                ExactNumberInfo::Precision(precision) => (Some(precision), None),
+                ExactNumberInfo::PrecisionAndScale(precision, scale) => {
+                    (Some(precision), Some(scale))
+                }
+            };
+            make_decimal_type(precision, scale)
+        }
+        SQLDataType::Bytea => Ok(DataType::Binary),
+        // Explicitly list all other types so that if sqlparser
+        // adds/changes the `SQLDataType` the compiler will tell us on upgrade
+        // and avoid bugs like https://github.com/apache/arrow-datafusion/issues/3059
+        SQLDataType::Nvarchar(_)
+        | SQLDataType::Uuid
+        | SQLDataType::Binary(_)
+        | SQLDataType::Varbinary(_)
+        | SQLDataType::Blob(_)
+        | SQLDataType::Datetime
+        | SQLDataType::Interval
+        | SQLDataType::Regclass
+        | SQLDataType::Custom(_)
+        | SQLDataType::Array(_)
+        | SQLDataType::Enum(_)
+        | SQLDataType::Set(_)
+        | SQLDataType::MediumInt(_)
+        | SQLDataType::UnsignedMediumInt(_)
+        | SQLDataType::Character(_)
+        | SQLDataType::CharacterVarying(_)
+        | SQLDataType::CharVarying(_)
+        | SQLDataType::CharacterLargeObject(_)
+        | SQLDataType::CharLargeObject(_)
+        | SQLDataType::Clob(_) => Err(DataFusionError::NotImplemented(format!(
+            "Unsupported SQL type {:?}",
+            sql_type
+        ))),
+    }
+}
+
+/// Convert SQL data type to relational representation of data type
+pub fn convert_data_type(sql_type: &SQLDataType) -> Result<DataType> {

Review Comment:
   Yeah, this is from a merge conflict. I will fix.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org