|
16 | 16 |
|
17 | 17 | package com.google.cloud.spanner.connection;
|
18 | 18 |
|
| 19 | +import static com.google.cloud.spanner.connection.StatementParserTest.assertUnclosedLiteral; |
19 | 20 | import static org.junit.Assert.assertEquals;
|
20 | 21 |
|
21 | 22 | import com.google.cloud.spanner.Dialect;
|
| 23 | +import com.google.cloud.spanner.connection.StatementParserTest.CommentInjector; |
22 | 24 | import org.junit.Test;
|
23 | 25 | import org.junit.runner.RunWith;
|
24 | 26 | import org.junit.runners.JUnit4;
|
@@ -80,4 +82,158 @@ public void testSkip() {
|
80 | 82 | assertEquals("'foo\\''", skip("r'foo\\'' ", 1));
|
81 | 83 | assertEquals("'''foo\\'\\'\\'bar'''", skip("'''foo\\'\\'\\'bar''' ", 0));
|
82 | 84 | }
|
| 85 | + |
| 86 | + @Test |
| 87 | + public void testConvertPositionalParametersToNamedParameters() { |
| 88 | + AbstractStatementParser parser = |
| 89 | + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL); |
| 90 | + |
| 91 | + for (String comment : |
| 92 | + new String[] { |
| 93 | + "-- test comment\n", |
| 94 | + "/* another test comment */", |
| 95 | + "/* comment\nwith\nmultiple\nlines\n */", |
| 96 | + "/* comment /* with nested */ comment */" |
| 97 | + }) { |
| 98 | + for (CommentInjector injector : CommentInjector.values()) { |
| 99 | + assertEquals( |
| 100 | + injector.inject("select * %sfrom foo where name=@p1", comment), |
| 101 | + parser.convertPositionalParametersToNamedParameters( |
| 102 | + '?', injector.inject("select * %sfrom foo where name=?", comment)) |
| 103 | + .sqlWithNamedParameters); |
| 104 | + assertEquals( |
| 105 | + injector.inject("@p1%s'?test?\"?test?\"?'@p2", comment), |
| 106 | + parser.convertPositionalParametersToNamedParameters( |
| 107 | + '?', injector.inject("?%s'?test?\"?test?\"?'?", comment)) |
| 108 | + .sqlWithNamedParameters); |
| 109 | + assertEquals( |
| 110 | + injector.inject("@p1'?it\\'?s'%s@p2", comment), |
| 111 | + parser.convertPositionalParametersToNamedParameters( |
| 112 | + '?', injector.inject("?'?it\\'?s'%s?", comment)) |
| 113 | + .sqlWithNamedParameters); |
| 114 | + assertEquals( |
| 115 | + injector.inject("@p1'?it\\\"?s'%s@p2", comment), |
| 116 | + parser.convertPositionalParametersToNamedParameters( |
| 117 | + '?', injector.inject("?'?it\\\"?s'%s?", comment)) |
| 118 | + .sqlWithNamedParameters); |
| 119 | + assertEquals( |
| 120 | + injector.inject("@p1\"?it\\\"?s\"%s@p2", comment), |
| 121 | + parser.convertPositionalParametersToNamedParameters( |
| 122 | + '?', injector.inject("?\"?it\\\"?s\"%s?", comment)) |
| 123 | + .sqlWithNamedParameters); |
| 124 | + assertEquals( |
| 125 | + injector.inject("@p1%s'''?it\\''?s'''@p2", comment), |
| 126 | + parser.convertPositionalParametersToNamedParameters( |
| 127 | + '?', injector.inject("?%s'''?it\\''?s'''?", comment)) |
| 128 | + .sqlWithNamedParameters); |
| 129 | + assertEquals( |
| 130 | + injector.inject("@p1\"\"\"?it\\\"\"?s\"\"\"%s@p2", comment), |
| 131 | + parser.convertPositionalParametersToNamedParameters( |
| 132 | + '?', injector.inject("?\"\"\"?it\\\"\"?s\"\"\"%s?", comment)) |
| 133 | + .sqlWithNamedParameters); |
| 134 | + |
| 135 | + // GoogleSQL does not support dollar-quoted strings, so these are all ignored. |
| 136 | + assertEquals( |
| 137 | + injector.inject("@p1$$@p2it$@p3s$$%s@p4", comment), |
| 138 | + parser.convertPositionalParametersToNamedParameters( |
| 139 | + '?', injector.inject("?$$?it$?s$$%s?", comment)) |
| 140 | + .sqlWithNamedParameters); |
| 141 | + assertEquals( |
| 142 | + injector.inject("@p1$tag$@p2it$$@p3s$tag$%s@p4", comment), |
| 143 | + parser.convertPositionalParametersToNamedParameters( |
| 144 | + '?', injector.inject("?$tag$?it$$?s$tag$%s?", comment)) |
| 145 | + .sqlWithNamedParameters); |
| 146 | + assertEquals( |
| 147 | + injector.inject("@p1%s$$@p2it\\'?s \t ?it\\'?s'$$@p3", comment), |
| 148 | + parser.convertPositionalParametersToNamedParameters( |
| 149 | + '?', injector.inject("?%s$$?it\\'?s \t ?it\\'?s'$$?", comment)) |
| 150 | + .sqlWithNamedParameters); |
| 151 | + |
| 152 | + // Note: GoogleSQL does not allowa a single-quoted string literal to contain line feeds. |
| 153 | + assertUnclosedLiteral(parser, injector.inject("?'?it\\''?s \n ?it\\''?s'%s?", comment)); |
| 154 | + assertEquals( |
| 155 | + "@p1'?it\\''@p2s \n @p3it\\''@p4s@p5", |
| 156 | + parser.convertPositionalParametersToNamedParameters('?', "?'?it\\''?s \n ?it\\''?s?") |
| 157 | + .sqlWithNamedParameters); |
| 158 | + assertEquals( |
| 159 | + injector.inject("@p1%s'''?it\\''?s \n ?it\\''?s'''@p2", comment), |
| 160 | + parser.convertPositionalParametersToNamedParameters( |
| 161 | + '?', injector.inject("?%s'''?it\\''?s \n ?it\\''?s'''?", comment)) |
| 162 | + .sqlWithNamedParameters); |
| 163 | + |
| 164 | + assertEquals( |
| 165 | + injector.inject( |
| 166 | + "select 1, @p1, 'test?test', \"test?test\", %sfoo.* from `foo` where col1=@p2 and col2='test' and col3=@p3 and col4='?' and col5=\"?\" and col6='?''?''?'", |
| 167 | + comment), |
| 168 | + parser.convertPositionalParametersToNamedParameters( |
| 169 | + '?', |
| 170 | + injector.inject( |
| 171 | + "select 1, ?, 'test?test', \"test?test\", %sfoo.* from `foo` where col1=? and col2='test' and col3=? and col4='?' and col5=\"?\" and col6='?''?''?'", |
| 172 | + comment)) |
| 173 | + .sqlWithNamedParameters); |
| 174 | + |
| 175 | + assertEquals( |
| 176 | + injector.inject( |
| 177 | + "select * " |
| 178 | + + "%sfrom foo " |
| 179 | + + "where name=@p1 " |
| 180 | + + "and col2 like @p2 " |
| 181 | + + "and col3 > @p3", |
| 182 | + comment), |
| 183 | + parser.convertPositionalParametersToNamedParameters( |
| 184 | + '?', |
| 185 | + injector.inject( |
| 186 | + "select * " |
| 187 | + + "%sfrom foo " |
| 188 | + + "where name=? " |
| 189 | + + "and col2 like ? " |
| 190 | + + "and col3 > ?", |
| 191 | + comment)) |
| 192 | + .sqlWithNamedParameters); |
| 193 | + assertEquals( |
| 194 | + injector.inject("select * " + "from foo " + "where id between @p1%s and @p2", comment), |
| 195 | + parser.convertPositionalParametersToNamedParameters( |
| 196 | + '?', |
| 197 | + injector.inject( |
| 198 | + "select * " + "from foo " + "where id between ?%s and ?", comment)) |
| 199 | + .sqlWithNamedParameters); |
| 200 | + assertEquals( |
| 201 | + injector.inject("select * " + "from foo " + "limit @p1 %s offset @p2", comment), |
| 202 | + parser.convertPositionalParametersToNamedParameters( |
| 203 | + '?', |
| 204 | + injector.inject("select * " + "from foo " + "limit ? %s offset ?", comment)) |
| 205 | + .sqlWithNamedParameters); |
| 206 | + assertEquals( |
| 207 | + injector.inject( |
| 208 | + "select * " |
| 209 | + + "from foo " |
| 210 | + + "where col1=@p1 " |
| 211 | + + "and col2 like @p2 " |
| 212 | + + " %s " |
| 213 | + + "and col3 > @p3 " |
| 214 | + + "and col4 < @p4 " |
| 215 | + + "and col5 != @p5 " |
| 216 | + + "and col6 not in (@p6, @p7, @p8) " |
| 217 | + + "and col7 in (@p9, @p10, @p11) " |
| 218 | + + "and col8 between @p12 and @p13", |
| 219 | + comment), |
| 220 | + parser.convertPositionalParametersToNamedParameters( |
| 221 | + '?', |
| 222 | + injector.inject( |
| 223 | + "select * " |
| 224 | + + "from foo " |
| 225 | + + "where col1=? " |
| 226 | + + "and col2 like ? " |
| 227 | + + " %s " |
| 228 | + + "and col3 > ? " |
| 229 | + + "and col4 < ? " |
| 230 | + + "and col5 != ? " |
| 231 | + + "and col6 not in (?, ?, ?) " |
| 232 | + + "and col7 in (?, ?, ?) " |
| 233 | + + "and col8 between ? and ?", |
| 234 | + comment)) |
| 235 | + .sqlWithNamedParameters); |
| 236 | + } |
| 237 | + } |
| 238 | + } |
83 | 239 | }
|
0 commit comments