From b41dac82b1f4b7fc7ae2f2315d49eaf1c0459d69 Mon Sep 17 00:00:00 2001 From: Primoz Kolaric Date: Thu, 5 Jan 2017 15:05:32 +0100 Subject: [PATCH] escape ? jsonb operator (used in postgresql 9.4+ https://www.postgresql.org/docs/9.4/static/functions-json.html) with double ?? - support for ?| and ?& added - test for ??, ?| and ?& operators - run testQuestionMarkExcaping only on postgresql 9.4+ --- .../com/impossibl/postgres/jdbc/SQLText.java | 18 ++++++++++++-- .../postgres/jdbc/StatementTest.java | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/impossibl/postgres/jdbc/SQLText.java b/src/main/java/com/impossibl/postgres/jdbc/SQLText.java index 792987d0f..bf432b6ad 100644 --- a/src/main/java/com/impossibl/postgres/jdbc/SQLText.java +++ b/src/main/java/com/impossibl/postgres/jdbc/SQLText.java @@ -128,8 +128,22 @@ public static MultiStatementNode parse(final String sql, boolean standardConform ndx = consumeQuotedIdentifier(sql, ndx, parents.peek()); continue; case '?': - ParameterPiece parameterPiece = new ParameterPiece(paramId++, ndx); - parents.peek().add(parameterPiece); + char nextChar = lookAhead(sql, ndx); + if (nextChar == '|' || nextChar == '&' || nextChar == '?') { + final GrammarPiece grammarPiece; + if (nextChar == '?') { + grammarPiece = new GrammarPiece("?", ndx); + } + else { + grammarPiece = new GrammarPiece("?" + nextChar, ndx); + } + parents.peek().add(grammarPiece); + ++ndx; + } + else { + ParameterPiece parameterPiece = new ParameterPiece(paramId++, ndx); + parents.peek().add(parameterPiece); + } break; case '$': ndx = consumeDollar(sql, ndx, parents.peek()); diff --git a/src/test/java/com/impossibl/postgres/jdbc/StatementTest.java b/src/test/java/com/impossibl/postgres/jdbc/StatementTest.java index 2da162f42..c58eebafa 100644 --- a/src/test/java/com/impossibl/postgres/jdbc/StatementTest.java +++ b/src/test/java/com/impossibl/postgres/jdbc/StatementTest.java @@ -609,4 +609,28 @@ public void testDefaultFetchSize() throws SQLException { ((PGConnection)con).setDefaultFetchSize(oldValue); } + + @Test + public void testQuestionMarkExcaping() throws SQLException { + if (!((PGConnection)con).isServerMinimumVersion(9, 4)) + return; + + Statement stmt = con.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT '{\"a\":1, \"b\":2}'::jsonb ?? 'b'"); + assertTrue(rs.next()); + assertEquals(true, rs.getBoolean(1)); + rs.close(); + + rs = stmt.executeQuery("SELECT '{\"a\":1, \"b\":2, \"c\":3}'::jsonb ?| array['b', 'd']"); + assertTrue(rs.next()); + assertEquals(true, rs.getBoolean(1)); + rs.close(); + + rs = stmt.executeQuery("SELECT '{\"a\":1, \"b\":2, \"c\":3}'::jsonb ?& array['b', 'd']"); + assertTrue(rs.next()); + assertEquals(false, rs.getBoolean(1)); + rs.close(); + + stmt.close(); + } }