@Test public void bindEmptyArrayOfStruct() { Type elementType = Type.struct(asList(Type.StructField.of("f1", Type.date()))); List<Struct> p = asList(); assertThat(p).isEmpty(); List<Struct> rows = resultRows( Statement.newBuilder("SELECT * FROM UNNEST(@p)") .bind("p") .toStructArray(elementType, p) .build(), elementType); assertThat(rows).isEmpty(); }
@Test public void bindReplacement() { String sql = "SELECT Name FROM Users WHERE Id = @id"; Statement stmt = Statement.newBuilder(sql).bind("id").to(1).bind("id").to(2).build(); assertThat(stmt.hasBinding("id")).isTrue(); assertThat(stmt.getSql()).isEqualTo(sql); assertThat(stmt.getParameters()).isEqualTo(ImmutableMap.of("id", Value.int64(2))); assertThat(stmt.toString()).isEqualTo(sql + " {id: 2}"); }
@Override public Struct read(ReadContext ctx, String key) { ResultSet resultSet = ctx.executeQuery( Statement.newBuilder("SELECT V FROM T WHERE K = @key") .bind("key") .to(key) .build()); assertThat(resultSet.next()).isTrue(); Struct row = resultSet.getCurrentRowAsStruct(); assertThat(resultSet.next()).isFalse(); return row; } });
@Test public void bindStructWithArrayOfStructField() { Struct arrayElement1 = Struct.newBuilder().set("ff1").to("abc").build(); Struct arrayElement2 = Struct.newBuilder().set("ff1").to("def").build(); Struct p = Struct.newBuilder() .set("f1") .toStructArray(arrayElement1.getType(), asList(arrayElement1, arrayElement2)) .build(); List<Struct> rows = resultRows( Statement.newBuilder("SELECT * FROM UNNEST(@p.f1)").bind("p").to(p).build(), arrayElement1.getType()); assertThat(rows.get(0).getString(0)).isEqualTo("abc"); assertThat(rows.get(1).getString(0)).isEqualTo("def"); }
@Test public void bindStructWithDuplicateFieldNames() { Struct p = Struct.newBuilder() .set("f1") .to(Value.int64(1337)) .set("f1") .to(Value.string("1337")) .build(); Struct row = executeWithRowResultType( Statement.newBuilder("SELECT * FROM UNNEST([@p])").bind("p").to(p).build(), p.getType()); assertThat(row.getLong(0)).isEqualTo(1337); assertThat(row.getString(1)).isEqualTo("1337"); }
@Test public void largeErrorText() { String veryLongString = Joiner.on("").join(Iterables.limit(Iterables.cycle("x"), 8000)); Statement statement = Statement.newBuilder("SELECT REGEXP_CONTAINS(@value, @regexp)") .bind("value") .to("") .bind("regexp") .to("(" + veryLongString) .build(); ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); expectedException.expect(isSpannerException(ErrorCode.OUT_OF_RANGE)); expectedException.expectMessage("Cannot parse regular expression"); resultSet.next(); }
@Test public void bindStructNull() { Struct row = execute( Statement.newBuilder("SELECT @p IS NULL") .bind("p") .to( Type.struct( asList( Type.StructField.of("f1", Type.string()), Type.StructField.of("f2", Type.float64()))), null) .build(), Type.bool()); assertThat(row.getBoolean(0)).isTrue(); }
@Test public void bindStruct() { Struct p = structValue(); String query = "SELECT " + "@p.f_int," + "@p.f_bool," + "@p.f_double," + "@p.f_timestamp," + "@p.f_date," + "@p.f_string," + "@p.f_bytes"; Struct row = executeWithRowResultType(Statement.newBuilder(query).bind("p").to(p).build(), p.getType()); assertThat(row).isEqualTo(p); }
private Struct execute(Statement.Builder builder, Type expectedColumnType) { return execute(builder.build(), expectedColumnType); } }
/** Creates a {@code Statement} with the given SQL text {@code sql}. */ public static Statement of(String sql) { return newBuilder(sql).build(); }
@Test public void invalidAmbiguousFieldAccess() { Struct p = Struct.newBuilder().set("f1").to(20).set("f1").to("abc").build(); expectedException.expect(isSpannerException(ErrorCode.INVALID_ARGUMENT)); expectedException.expectMessage("Struct field name f1 is ambiguous"); execute(Statement.newBuilder("SELECT @p.f1").bind("p").to(p).build(), Type.int64()); }
@Test public void bindStructWithStructField() { Struct nestedStruct = Struct.newBuilder().set("ff1").to("abc").build(); Struct p = Struct.newBuilder().set("f1").to(nestedStruct).build(); Struct row = executeWithRowResultType( Statement.newBuilder("SELECT @p.f1.ff1").bind("p").to(p).build(), nestedStruct.getType()); assertThat(row.getString(0)).isEqualTo("abc"); }
@Test public void bindStructWithNullStructField() { Type emptyStructType = Type.struct(new ArrayList<StructField>()); Struct p = Struct.newBuilder().set("f1").to(emptyStructType, null).build(); Struct row = execute(Statement.newBuilder("SELECT @p.f1 IS NULL").bind("p").to(p).build(), Type.bool()); assertThat(row.getBoolean(0)).isTrue(); }
@Test public void unsupportedSelectStructValue() { Struct p = structValue(); expectedException.expect(isSpannerException(ErrorCode.UNIMPLEMENTED)); expectedException.expectMessage( "Unsupported query shape: " + "A struct value cannot be returned as a column value."); execute(Statement.newBuilder("SELECT @p").bind("p").to(p).build(), p.getType()); }
@Test public void bindStructWithUnnamedFields() { Struct p = Struct.newBuilder().add(Value.int64(1337)).add(Value.int64(7331)).build(); Struct row = executeWithRowResultType( Statement.newBuilder("SELECT * FROM UNNEST([@p])").bind("p").to(p).build(), p.getType()); assertThat(row.getLong(0)).isEqualTo(1337); assertThat(row.getLong(1)).isEqualTo(7331); }
@Test public void bindBool() { Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(true).build(), Type.bool()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBoolean(0)).isEqualTo(true); }
private void keepAlive() { markUsed(); delegate .singleUse(TimestampBound.ofMaxStaleness(60, TimeUnit.SECONDS)) .executeQuery(Statement.newBuilder("SELECT 1").build()) .next(); }
@Test public void bindEmptyStruct() { Struct p = Struct.newBuilder().build(); Struct row = execute(Statement.newBuilder("SELECT @p IS NULL").bind("p").to(p).build(), Type.bool()); assertThat(row.getBoolean(0)).isFalse(); }
@Test public void incompleteBinding() { Statement.Builder builder = Statement.newBuilder("SELECT @v"); builder.bind("v"); expectedException.expect(IllegalStateException.class); builder.build(); }
@Test public void unsupportedSelectArrayStructValue() { Struct p = structValue(); expectedException.expect(isSpannerException(ErrorCode.UNIMPLEMENTED)); expectedException.expectMessage( "Unsupported query shape: " + "This query can return a null-valued array of struct, " + "which is not supported by Spanner."); execute( Statement.newBuilder("SELECT @p").bind("p").toStructArray(p.getType(), asList(p)).build(), p.getType()); }