sqlkata / querybuilder

SQL query builder, written in c#, helps you build complex queries easily, supports SqlServer, MySql, PostgreSql, Oracle, Sqlite and Firebird
https://sqlkata.com
MIT License
3.12k stars 502 forks source link

Odd wrapping behavior #583

Closed RFBomb closed 2 years ago

RFBomb commented 2 years ago

I'm running this through some unit tests to play around with it while building myself a compiler to work with an AccessDB, and introduce the 'ALIKE' keyword to be in used of 'LIKE' or 'ILIKE'.

I've specified the Opening/Closing identified to [ & ]. What I've noticed is that if [TestCol2] is passed in, this library 'sanitizes' it to [[TestCol2]]] (Note 2 in front, 3 in rear)

https://github.com/sqlkata/querybuilder/blob/1646bed4bfd17d98e32cc3cd5351faa551bc8c76/QueryBuilder/Compilers /Compiler.cs#L800

is that correct? I browsed some of the unit tests in this library and didn't see this particular condition. Instead, most of the tests pass in values without any identifiers, which results in the expected [ColumnName]

The other question I have is with 'Wrap', 'WrapValue' and 'WrapIdentifiers'. Wrap/WrapValue appear to be primarily concerned with table names and other key values (such as the alias when using the AS statement), while WrapIdentifiers is involved with the table names almost exclusively. Why not use the 'WrapIdentifiers' for columns?

And finally, I just wanted to verify the function of the ReplaceIdentifierUnlessEscaped extension method.

When provided a value of \{ Test } is returns { Test ].

RFBomb commented 2 years ago

Adding a note here since I'm building a compiler for an Access database - The WrapValue method wasn't working due to the above issue. Access was not accepting [[ColumnName]]], nor was it accepting anything with more than a single set of brackets. I resolved it with a simple regex test within my compiler for now.

//language=Regex
        static Regex valueRegex { get; } = new Regex(@"^\[.+?\]", RegexOptions.Compiled);

        /// <inheritdoc/>
        public override string WrapValue(string value)
        {
            if (valueRegex.IsMatch(value)) return value;
            return base.WrapValue(value);
        }
ahmad-moussawi commented 2 years ago

since the Wrap method is designed to escape identifiers, you have to override it and implement your own logic.