Skip to content

Interval multiplication parses differently depending on operand order #1345

Closed
@mcheshkov

Description

@mcheshkov

Depending on operands order, intervals without leading fields (with literal alone) parses differently.

I've checked on sqlparser = "0.48.0"
SELECT 1 * interval '1 month'; parses as BinOp(Number, Interval(String)), which, I think, is correct:

projection: [
    UnnamedExpr(
        BinaryOp {
            left: Value(
                Number(
                    "1",
                    false,
                ),
            ),
            op: Multiply,
            right: Interval(
                Interval {
                    value: Value(
                        SingleQuotedString(
                            "1 month",
                        ),
                    ),
// ...
                },
            ),
        },
    ),
],

But SELECT interval '1 month' * 1; parses as Interval(BinOp(String, Number)), which, to me, is incorrect:

projection: [
    UnnamedExpr(
        Interval(
            Interval {
                value: BinaryOp {
                    left: Value(
                        SingleQuotedString(
                            "1 month",
                        ),
                    ),
                    op: Multiply,
                    right: Value(
                        Number(
                            "1",
                            false,
                        ),
                    ),
                },
// ...
            },
        ),
    ),
],

I think that culprit is these calls
https://github.com/sqlparser-rs/sqlparser-rs/blob/20f7ac59e38d52e293476b7ad844e7f744a16c43/src/parser/mod.rs#L2027
=>
https://github.com/sqlparser-rs/sqlparser-rs/blob/20f7ac59e38d52e293476b7ad844e7f744a16c43/src/parser/mod.rs#L906

It would consume not only literals, but any expression as well, and store result as Intervals value

I propose to change parse_interval_expr so it would allow only literals, or maybe even replace it with parse_value.
I didn't actually check if that would break any tests, but at first glance it should not.

Also representation of interval value in AST could be changed from Expr to Value, but that would break public API, so could be postponed.

Related:
#517
#705

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions