Skip to content

Commit 59ba100

Browse files
committed
Issue #26: Enhance Access '^' power operator translation to SQL POWER()
Extends operator translation to include support for parameter markers ('?'). This ensures correct translation of SQL queries used with PreparedStatements. Updated the POWER_OPERAND_REGEX to recognize '?' and added corresponding unit tests.
1 parent 12c9768 commit 59ba100

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

src/main/java/net/ucanaccess/converters/SQLConverter.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ public static final class Patterns {
6161
private static final String POWER_OPERAND_REGEX =
6262
"(?:"
6363
+ "\\b[a-zA-Z_][a-zA-Z0-9_.]*\\b" // column name/identifier
64-
+ "|"
64+
+ '|'
6565
+ "[+-]?\\d+(?:\\.\\d*)?(?:e[+-]?\\d+)?" // numeric term
66-
+ "|"
66+
+ '|'
6767
+ "\\([^()]+?\\)" // simple parenthesized expressions WITHOUT nested parentheses
68+
+ '|'
69+
+ "\\?" // parameter marker for PreparedStatements
6870
+ ")";
6971

7072
// the main pattern to find "operand1 ^ operand2"
@@ -549,13 +551,14 @@ private static String replaceWhiteSpacedTableNames0(String sql) {
549551
* <p>
550552
* This is a simplified implementation based on regular expressions and might not
551553
* cover all edge cases or complex SQL constructs. For robust parsing and
552-
* modification of SQL, we should use a dedicated SQL parser library e.g. JSqlParser.
554+
* modification of SQL, we should use a dedicated SQL parser library e.g. JSqlParser.
553555
*
554556
* <p>The current implementation's {@code POWER_OPERAND_REGEX} is designed to identify:</p>
555557
* <ul>
556558
* <li>Simple column names or identifiers (e.g., {@code myColumn}, {@code Table.Column}).</li>
557559
* <li>Numeric literals (integers, decimals, scientific notation, with optional sign).</li>
558560
* <li>Simple parenthesized expressions without nested parentheses (e.g., {@code (num + 1)}).</li>
561+
* <li>Parameter markers ({@code ?}) for use in {@code PreparedStatement} scenarios.</li>
559562
* </ul>
560563
* <p>It explicitly **does NOT reliably handle** operands that are:</p>
561564
* <ul>

src/test/java/net/ucanaccess/converters/SQLConverterTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ private static Stream<Arguments> provideSqlTranslationData() {
6868
// Edge cases: Subqueries (NOT supported by regex for operands) - should remain unchanged
6969
//arguments("SELECT (SELECT X FROM Y)^2 FROM T", "SELECT (SELECT X FROM Y)^2 FROM T", "Subquery (base) - not handled"),
7070

71+
// parameter markers (?) for use in PreparedStatement
72+
arguments("SELECT num^? FROM t", "SELECT POWER(num, ?) FROM t", "parameter marker 1a"),
73+
arguments("SELECT num ^ ? FROM t", "SELECT POWER(num, ?) FROM t", "parameter marker 1b"),
74+
arguments("SELECT ?^num FROM t", "SELECT POWER(?, num) FROM t", "parameter marker 2a"),
75+
arguments("SELECT ? ^ num FROM t", "SELECT POWER(?, num) FROM t", "parameter marker 2b"),
76+
arguments("SELECT ?^? FROM t", "SELECT POWER(?, ?) FROM t", "parameter marker 3a"),
77+
arguments("SELECT ? ^ ? FROM t", "SELECT POWER(?, ?) FROM t", "parameter marker 3b"),
78+
7179
// Test with empty string or null input
7280
arguments(null, null, "Null input"),
7381
arguments("", "", "Empty string input"),

0 commit comments

Comments
 (0)