2727import static org .junit .Assert .assertNotNull ;
2828import static org .junit .Assert .fail ;
2929import static org .junit .Assume .assumeFalse ;
30+ import static org .junit .Assume .assumeTrue ;
3031
3132import com .google .cloud .ByteArray ;
3233import com .google .cloud .Date ;
5152import com .google .cloud .spanner .connection .ConnectionOptions ;
5253import com .google .cloud .spanner .testing .EmulatorSpannerHelper ;
5354import com .google .common .collect .ImmutableList ;
55+ import com .google .protobuf .NullValue ;
5456import io .grpc .Context ;
5557import java .math .BigDecimal ;
5658import java .util .ArrayList ;
@@ -98,8 +100,7 @@ public static List<DialectTestParameter> data() {
98100 private static DatabaseClient googleStandardSQLClient ;
99101 private static DatabaseClient postgreSQLClient ;
100102
101- // TODO: Remove when the emulator supports NUMERIC and JSON
102- private static final String GOOGLE_STANDARD_SQL_SCHEMA_WITH_NUMERIC_AND_JSON =
103+ private static final String GOOGLE_STANDARD_SQL_SCHEMA =
103104 "CREATE TABLE T ("
104105 + " K STRING(MAX) NOT NULL,"
105106 + " BoolValue BOOL,"
@@ -122,13 +123,14 @@ public static List<DialectTestParameter> data() {
122123 + " NumericArrayValue ARRAY<NUMERIC>,"
123124 + ") PRIMARY KEY (K)" ;
124125
125- private static final String POSTGRESQL_SCHEMA_WITH_NUMERIC =
126+ private static final String POSTGRESQL_SCHEMA =
126127 "CREATE TABLE T ("
127128 + " K VARCHAR PRIMARY KEY,"
128129 + " BoolValue BOOL,"
129130 + " Int64Value BIGINT,"
130131 + " Float64Value DOUBLE PRECISION,"
131132 + " StringValue VARCHAR,"
133+ + " JsonValue JSONB,"
132134 + " BytesValue BYTEA,"
133135 + " TimestampValue TIMESTAMPTZ,"
134136 + " DateValue DATE,"
@@ -137,31 +139,13 @@ public static List<DialectTestParameter> data() {
137139 + " Int64ArrayValue BIGINT[],"
138140 + " Float64ArrayValue DOUBLE PRECISION[],"
139141 + " StringArrayValue VARCHAR[],"
142+ + " JsonArrayValue JSONB[],"
140143 + " BytesArrayValue BYTEA[],"
141144 + " TimestampArrayValue TIMESTAMPTZ[],"
142145 + " DateArrayValue DATE[],"
143146 + " NumericArrayValue NUMERIC[]"
144147 + ")" ;
145148
146- private static final String GOOGLE_STANDARD_SQL_SCHEMA_WITHOUT_NUMERIC_AND_JSON =
147- "CREATE TABLE T ("
148- + " K STRING(MAX) NOT NULL,"
149- + " BoolValue BOOL,"
150- + " Int64Value INT64,"
151- + " Float64Value FLOAT64,"
152- + " StringValue STRING(MAX),"
153- + " BytesValue BYTES(MAX),"
154- + " TimestampValue TIMESTAMP OPTIONS (allow_commit_timestamp = true),"
155- + " DateValue DATE,"
156- + " BoolArrayValue ARRAY<BOOL>,"
157- + " Int64ArrayValue ARRAY<INT64>,"
158- + " Float64ArrayValue ARRAY<FLOAT64>,"
159- + " StringArrayValue ARRAY<STRING(MAX)>,"
160- + " BytesArrayValue ARRAY<BYTES(MAX)>,"
161- + " TimestampArrayValue ARRAY<TIMESTAMP>,"
162- + " DateArrayValue ARRAY<DATE>,"
163- + ") PRIMARY KEY (K)" ;
164-
165149 /** Sequence used to generate unique keys. */
166150 private static int seq ;
167151
@@ -170,21 +154,14 @@ public static List<DialectTestParameter> data() {
170154 @ BeforeClass
171155 public static void setUpDatabase ()
172156 throws ExecutionException , InterruptedException , TimeoutException {
173- if (EmulatorSpannerHelper .isUsingEmulator ()) {
174- Database googleStandardSQLDatabase =
175- env .getTestHelper ()
176- .createTestDatabase (GOOGLE_STANDARD_SQL_SCHEMA_WITHOUT_NUMERIC_AND_JSON );
177-
178- googleStandardSQLClient = env .getTestHelper ().getDatabaseClient (googleStandardSQLDatabase );
179- } else {
180- Database googleStandardSQLDatabase =
181- env .getTestHelper ().createTestDatabase (GOOGLE_STANDARD_SQL_SCHEMA_WITH_NUMERIC_AND_JSON );
157+ Database googleStandardSQLDatabase =
158+ env .getTestHelper ().createTestDatabase (GOOGLE_STANDARD_SQL_SCHEMA );
182159
183- googleStandardSQLClient = env .getTestHelper ().getDatabaseClient (googleStandardSQLDatabase );
160+ googleStandardSQLClient = env .getTestHelper ().getDatabaseClient (googleStandardSQLDatabase );
161+ if (!EmulatorSpannerHelper .isUsingEmulator ()) {
184162 Database postgreSQLDatabase =
185163 env .getTestHelper ()
186- .createTestDatabase (
187- Dialect .POSTGRESQL , Collections .singletonList (POSTGRESQL_SCHEMA_WITH_NUMERIC ));
164+ .createTestDatabase (Dialect .POSTGRESQL , Collections .singletonList (POSTGRESQL_SCHEMA ));
188165 postgreSQLClient = env .getTestHelper ().getDatabaseClient (postgreSQLDatabase );
189166 }
190167 }
@@ -396,7 +373,6 @@ public void writeStringNull() {
396373
397374 @ Test
398375 public void writeJson () {
399- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
400376 assumeFalse ("PostgreSQL does not yet support JSON" , dialect .dialect == Dialect .POSTGRESQL );
401377 write (baseInsert ().set ("JsonValue" ).to (Value .json ("{\" rating\" :9,\" open\" :true}" )).build ());
402378 Struct row = readLastRow ("JsonValue" );
@@ -407,7 +383,6 @@ public void writeJson() {
407383
408384 @ Test
409385 public void writeJsonEmpty () {
410- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
411386 assumeFalse ("PostgreSQL does not yet support JSON" , dialect .dialect == Dialect .POSTGRESQL );
412387 write (baseInsert ().set ("JsonValue" ).to (Value .json ("{}" )).build ());
413388 Struct row = readLastRow ("JsonValue" );
@@ -418,7 +393,6 @@ public void writeJsonEmpty() {
418393
419394 @ Test
420395 public void writeJsonNull () {
421- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
422396 assumeFalse ("PostgreSQL does not yet support JSON" , dialect .dialect == Dialect .POSTGRESQL );
423397 write (baseInsert ().set ("JsonValue" ).to (Value .json (null )).build ());
424398 Struct row = readLastRow ("JsonValue" );
@@ -588,7 +562,6 @@ public void writeDateNull() {
588562
589563 @ Test
590564 public void writeNumeric () {
591- assumeFalse ("Emulator does not yet support NUMERIC" , EmulatorSpannerHelper .isUsingEmulator ());
592565 write (baseInsert ().set ("NumericValue" ).to ("3.141592" ).build ());
593566 Struct row = readLastRow ("NumericValue" );
594567 assertThat (row .isNull (0 )).isFalse ();
@@ -601,7 +574,6 @@ public void writeNumeric() {
601574
602575 @ Test
603576 public void writeNumericNull () {
604- assumeFalse ("Emulator does not yet support NUMERIC" , EmulatorSpannerHelper .isUsingEmulator ());
605577 write (baseInsert ().set ("NumericValue" ).to ((String ) null ).build ());
606578 Struct row = readLastRow ("NumericValue" );
607579 assertThat (row .isNull (0 )).isTrue ();
@@ -751,7 +723,6 @@ public void writeStringArray() {
751723 @ Test
752724 public void writeJsonArrayNull () {
753725 assumeFalse ("PostgreSQL does not yet support Array" , dialect .dialect == Dialect .POSTGRESQL );
754- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
755726 write (baseInsert ().set ("JsonArrayValue" ).toJsonArray (null ).build ());
756727 Struct row = readLastRow ("JsonArrayValue" );
757728 assertThat (row .isNull (0 )).isTrue ();
@@ -761,7 +732,6 @@ public void writeJsonArrayNull() {
761732 @ Test
762733 public void writeJsonArrayEmpty () {
763734 assumeFalse ("PostgreSQL does not yet support Array" , dialect .dialect == Dialect .POSTGRESQL );
764- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
765735 write (baseInsert ().set ("JsonArrayValue" ).toJsonArray (Collections .emptyList ()).build ());
766736 Struct row = readLastRow ("JsonArrayValue" );
767737 assertThat (row .isNull (0 )).isFalse ();
@@ -772,7 +742,6 @@ public void writeJsonArrayEmpty() {
772742 @ Test
773743 public void writeJsonArray () {
774744 assumeFalse ("PostgreSQL does not yet support Array" , dialect .dialect == Dialect .POSTGRESQL );
775- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
776745 write (baseInsert ().set ("JsonArrayValue" ).toJsonArray (Arrays .asList ("[]" , null , "{}" )).build ());
777746 Struct row = readLastRow ("JsonArrayValue" );
778747 assertThat (row .isNull (0 )).isFalse ();
@@ -783,7 +752,6 @@ public void writeJsonArray() {
783752 @ Test
784753 public void writeJsonArrayNoNulls () {
785754 assumeFalse ("PostgreSQL does not yet support Array" , dialect .dialect == Dialect .POSTGRESQL );
786- assumeFalse ("Emulator does not yet support JSON" , EmulatorSpannerHelper .isUsingEmulator ());
787755 write (
788756 baseInsert ()
789757 .set ("JsonArrayValue" )
@@ -878,15 +846,13 @@ public void writeDateArray() {
878846
879847 @ Test
880848 public void writeNumericArrayNull () {
881- assumeFalse ("Emulator does not yet support NUMERIC" , EmulatorSpannerHelper .isUsingEmulator ());
882849 write (baseInsert ().set ("NumericArrayValue" ).toNumericArray (null ).build ());
883850 Struct row = readLastRow ("NumericArrayValue" );
884851 assertThat (row .isNull (0 )).isTrue ();
885852 }
886853
887854 @ Test
888855 public void writeNumericArrayEmpty () {
889- assumeFalse ("Emulator does not yet support NUMERIC" , EmulatorSpannerHelper .isUsingEmulator ());
890856 write (baseInsert ().set ("NumericArrayValue" ).toNumericArray (ImmutableList .of ()).build ());
891857 Struct row = readLastRow ("NumericArrayValue" );
892858 assertThat (row .isNull (0 )).isFalse ();
@@ -899,7 +865,6 @@ public void writeNumericArrayEmpty() {
899865
900866 @ Test
901867 public void writeNumericArray () {
902- assumeFalse ("Emulator does not yet support NUMERIC" , EmulatorSpannerHelper .isUsingEmulator ());
903868 write (
904869 baseInsert ()
905870 .set ("NumericArrayValue" )
@@ -918,7 +883,6 @@ public void writeNumericArray() {
918883
919884 @ Test
920885 public void writeNumericArrayNoNulls () {
921- assumeFalse ("Emulator does not yet support NUMERIC" , EmulatorSpannerHelper .isUsingEmulator ());
922886 write (
923887 baseInsert ()
924888 .set ("NumericArrayValue" )
@@ -1013,4 +977,160 @@ public void deadline() {
1013977 executor .shutdown ();
1014978 }
1015979 }
980+
981+ @ Test
982+ public void testWriteUntypedNullValuesGoogleSQL () {
983+ assumeFalse (
984+ "PostgreSQL uses a different parameter format" , dialect .dialect == Dialect .POSTGRESQL );
985+ Value untypedNull =
986+ Value .untyped (
987+ com .google .protobuf .Value .newBuilder ().setNullValue (NullValue .NULL_VALUE ).build ());
988+ assertEquals (
989+ Long .valueOf (1L ),
990+ client
991+ .readWriteTransaction ()
992+ .run (
993+ transaction ->
994+ transaction .executeUpdate (
995+ Statement .newBuilder (
996+ "insert into T ("
997+ + "K,"
998+ + "BoolValue,"
999+ + "Int64Value,"
1000+ + "Float64Value,"
1001+ + "StringValue,"
1002+ + "JsonValue,"
1003+ + "BytesValue,"
1004+ + "TimestampValue,"
1005+ + "DateValue,"
1006+ + "NumericValue,"
1007+ + "BoolArrayValue,"
1008+ + "Int64ArrayValue,"
1009+ + "Float64ArrayValue,"
1010+ + "StringArrayValue,"
1011+ + "JsonArrayValue,"
1012+ + "BytesArrayValue,"
1013+ + "TimestampArrayValue,"
1014+ + "DateArrayValue,"
1015+ + "NumericArrayValue"
1016+ + ") values (@k, @bool, @int64, @float64, @string, @json, @bytes, @timestamp, @date, @numeric, "
1017+ + "@boolArray, @int64Array, @float64Array, @stringArray, @jsonArray, @bytesArray, @timestampArray, @dateArray, @numericArray)" )
1018+ .bind ("k" )
1019+ .to (uniqueString ())
1020+ .bind ("bool" )
1021+ .to (untypedNull )
1022+ .bind ("int64" )
1023+ .to (untypedNull )
1024+ .bind ("float64" )
1025+ .to (untypedNull )
1026+ .bind ("string" )
1027+ .to (untypedNull )
1028+ .bind ("json" )
1029+ .to (untypedNull )
1030+ .bind ("bytes" )
1031+ .to (untypedNull )
1032+ .bind ("timestamp" )
1033+ .to (untypedNull )
1034+ .bind ("date" )
1035+ .to (untypedNull )
1036+ .bind ("numeric" )
1037+ .to (untypedNull )
1038+ .bind ("boolArray" )
1039+ .to (untypedNull )
1040+ .bind ("int64Array" )
1041+ .to (untypedNull )
1042+ .bind ("float64Array" )
1043+ .to (untypedNull )
1044+ .bind ("stringArray" )
1045+ .to (untypedNull )
1046+ .bind ("jsonArray" )
1047+ .to (untypedNull )
1048+ .bind ("bytesArray" )
1049+ .to (untypedNull )
1050+ .bind ("timestampArray" )
1051+ .to (untypedNull )
1052+ .bind ("dateArray" )
1053+ .to (untypedNull )
1054+ .bind ("numericArray" )
1055+ .to (untypedNull )
1056+ .build ())));
1057+ }
1058+
1059+ @ Test
1060+ public void testWriteUntypedNullValuesPostgreSQL () {
1061+ assumeTrue (
1062+ "PostgreSQL uses a different parameter format" , dialect .dialect == Dialect .POSTGRESQL );
1063+ Value untypedNull =
1064+ Value .untyped (
1065+ com .google .protobuf .Value .newBuilder ().setNullValue (NullValue .NULL_VALUE ).build ());
1066+ assertEquals (
1067+ Long .valueOf (1L ),
1068+ client
1069+ .readWriteTransaction ()
1070+ .run (
1071+ transaction ->
1072+ transaction .executeUpdate (
1073+ Statement .newBuilder (
1074+ "insert into T ("
1075+ + "K,"
1076+ + "BoolValue,"
1077+ + "Int64Value,"
1078+ + "Float64Value,"
1079+ + "StringValue,"
1080+ + "JsonValue,"
1081+ + "BytesValue,"
1082+ + "TimestampValue,"
1083+ + "DateValue,"
1084+ + "NumericValue,"
1085+ + "BoolArrayValue,"
1086+ + "Int64ArrayValue,"
1087+ + "Float64ArrayValue,"
1088+ + "StringArrayValue,"
1089+ + "JsonArrayValue,"
1090+ + "BytesArrayValue,"
1091+ + "TimestampArrayValue,"
1092+ + "DateArrayValue,"
1093+ + "NumericArrayValue"
1094+ + ") values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, "
1095+ + "$11, $12, $13, $14, $15, $16, $17, $18, $19)" )
1096+ .bind ("p1" )
1097+ .to (uniqueString ())
1098+ .bind ("p2" )
1099+ .to (untypedNull )
1100+ .bind ("p3" )
1101+ .to (untypedNull )
1102+ .bind ("p4" )
1103+ .to (untypedNull )
1104+ .bind ("p5" )
1105+ .to (untypedNull )
1106+ .bind ("p6" )
1107+ .to (untypedNull )
1108+ .bind ("p7" )
1109+ .to (untypedNull )
1110+ .bind ("p8" )
1111+ .to (untypedNull )
1112+ .bind ("p9" )
1113+ .to (untypedNull )
1114+ .bind ("p10" )
1115+ .to (untypedNull )
1116+ .bind ("p11" )
1117+ .to (untypedNull )
1118+ .bind ("p12" )
1119+ .to (untypedNull )
1120+ .bind ("p13" )
1121+ .to (untypedNull )
1122+ .bind ("p14" )
1123+ .to (untypedNull )
1124+ .bind ("p15" )
1125+ .to (untypedNull )
1126+ .bind ("p16" )
1127+ .to (untypedNull )
1128+ .bind ("p17" )
1129+ .to (untypedNull )
1130+ .bind ("p18" )
1131+ .to (untypedNull )
1132+ .bind ("p19" )
1133+ .to (untypedNull )
1134+ .build ())));
1135+ }
10161136}
0 commit comments