diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParser.java index 404b180aab..460c68cbe2 100644 --- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParser.java +++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParser.java @@ -89,11 +89,7 @@ public ArrayParser( case TEXT: this.item = stringArrayToList( - new String(item, StandardCharsets.UTF_8), - elementOid, - this.isStringEquivalent, - this.sessionState, - false); + new String(item, StandardCharsets.UTF_8), elementOid, this.sessionState, false); break; case BINARY: this.item = binaryArrayToList(item, false); @@ -138,14 +134,12 @@ private List toList(Value value, Code arrayElementType) { public static List stringArrayToList( @Nullable String value, int elementOid, - boolean isStringEquivalent, SessionState sessionState, boolean convertToValidSpannerElements) { if (value == null) { return null; } - List values = - SimpleParser.readArrayLiteral(value, isStringEquivalent, elementOid == Oid.BYTEA); + List values = SimpleParser.readArrayLiteral(value, elementOid == Oid.BYTEA); ArrayList result = new ArrayList<>(values.size()); for (String element : values) { if (element == null) { diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SimpleParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SimpleParser.java index 506aa82769..1171e9684c 100644 --- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/SimpleParser.java +++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/SimpleParser.java @@ -275,8 +275,7 @@ public static boolean isCommand(String command, String query) { return new SimpleParser(query).peekKeyword(command); } - public static List readArrayLiteral( - String expression, boolean mustBeQuoted, boolean returnRawHexValue) { + public static List readArrayLiteral(String expression, boolean returnRawHexValue) { List result = new ArrayList<>(); SimpleParser parser = new SimpleParser(expression); if (!parser.eatToken("{")) { @@ -288,7 +287,7 @@ public static List readArrayLiteral( break; } else if (parser.eatKeyword("null")) { result.add(null); - } else if (mustBeQuoted || parser.peekToken("\"")) { + } else if (parser.peekToken("\"")) { QuotedString quotedString = parser.readQuotedString('"', true); if (quotedString == null) { throw PGExceptionFactory.newPGException( diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/utils/CsvCopyParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/utils/CsvCopyParser.java index 5d83144b63..9d307c2013 100644 --- a/src/main/java/com/google/cloud/spanner/pgadapter/utils/CsvCopyParser.java +++ b/src/main/java/com/google/cloud/spanner/pgadapter/utils/CsvCopyParser.java @@ -170,49 +170,39 @@ static Value getSpannerValue(SessionState sessionState, Type type, String record switch (type.getArrayElementType().getCode()) { case STRING: return Value.stringArray( - cast( - ArrayParser.stringArrayToList( - recordValue, Oid.TEXT, false, sessionState, true))); + cast(ArrayParser.stringArrayToList(recordValue, Oid.TEXT, sessionState, true))); case PG_JSONB: return Value.pgJsonbArray( cast( - ArrayParser.stringArrayToList( - recordValue, Oid.JSONB, false, sessionState, true))); + ArrayParser.stringArrayToList(recordValue, Oid.JSONB, sessionState, true))); case BOOL: return Value.boolArray( - cast( - ArrayParser.stringArrayToList( - recordValue, Oid.BOOL, false, sessionState, true))); + cast(ArrayParser.stringArrayToList(recordValue, Oid.BOOL, sessionState, true))); case INT64: return Value.int64Array( - cast( - ArrayParser.stringArrayToList( - recordValue, Oid.INT8, false, sessionState, true))); + cast(ArrayParser.stringArrayToList(recordValue, Oid.INT8, sessionState, true))); case FLOAT64: return Value.float64Array( cast( ArrayParser.stringArrayToList( - recordValue, Oid.FLOAT8, false, sessionState, true))); + recordValue, Oid.FLOAT8, sessionState, true))); case PG_NUMERIC: return Value.pgNumericArray( cast( ArrayParser.stringArrayToList( - recordValue, Oid.NUMERIC, false, sessionState, true))); + recordValue, Oid.NUMERIC, sessionState, true))); case BYTES: return Value.bytesArray( cast( - ArrayParser.stringArrayToList( - recordValue, Oid.BYTEA, false, sessionState, true))); + ArrayParser.stringArrayToList(recordValue, Oid.BYTEA, sessionState, true))); case DATE: return Value.dateArray( - cast( - ArrayParser.stringArrayToList( - recordValue, Oid.DATE, false, sessionState, true))); + cast(ArrayParser.stringArrayToList(recordValue, Oid.DATE, sessionState, true))); case TIMESTAMP: return Value.timestampArray( cast( ArrayParser.stringArrayToList( - recordValue, Oid.TIMESTAMPTZ, false, sessionState, true))); + recordValue, Oid.TIMESTAMPTZ, sessionState, true))); } default: SpannerException spannerException = diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParserTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParserTest.java index 8d6ef1dc27..f858fba81a 100644 --- a/src/test/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParserTest.java +++ b/src/test/java/com/google/cloud/spanner/pgadapter/parsers/ArrayParserTest.java @@ -189,6 +189,19 @@ public void testTimestamp() { Type.timestamp(), Oid.TIMESTAMPTZ) .item); + assertEquals( + Arrays.asList( + Timestamp.parseTimestamp("2023-02-13T19:15:00.123456Z"), + null, + Timestamp.parseTimestamp("2000-01-01T00:00:00Z")), + new ArrayParser( + "{2023-02-13T19:15:00.123456+00:00,null,2000-01-01T00:00:00+00}" + .getBytes(StandardCharsets.UTF_8), + FormatCode.TEXT, + mock(SessionState.class), + Type.timestamp(), + Oid.TIMESTAMPTZ) + .item); } @Test @@ -202,6 +215,15 @@ public void testDate() { Type.date(), Oid.DATE) .item); + assertEquals( + Arrays.asList(Date.parseDate("2023-02-13"), null, Date.parseDate("2000-01-01")), + new ArrayParser( + "{2023-02-13,null,2000-01-01}".getBytes(StandardCharsets.UTF_8), + FormatCode.TEXT, + mock(SessionState.class), + Type.date(), + Oid.DATE) + .item); } @Test @@ -451,16 +473,13 @@ public void testNullBinaryArray() { @Test public void testNullTextArray() { assertNull( - ArrayParser.stringArrayToList( - null, Oid.UNSPECIFIED, false, mock(SessionState.class), false)); + ArrayParser.stringArrayToList(null, Oid.UNSPECIFIED, mock(SessionState.class), false)); assertNull( - ArrayParser.stringArrayToList( - null, Oid.UNSPECIFIED, false, mock(SessionState.class), true)); + ArrayParser.stringArrayToList(null, Oid.UNSPECIFIED, mock(SessionState.class), true)); assertNull( - ArrayParser.stringArrayToList( - null, Oid.UNSPECIFIED, true, mock(SessionState.class), false)); + ArrayParser.stringArrayToList(null, Oid.UNSPECIFIED, mock(SessionState.class), false)); assertNull( - ArrayParser.stringArrayToList(null, Oid.UNSPECIFIED, true, mock(SessionState.class), true)); + ArrayParser.stringArrayToList(null, Oid.UNSPECIFIED, mock(SessionState.class), true)); } static ResultSet createArrayResultSet(Type arrayElementType, Value value) { diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/statements/SimpleParserTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/statements/SimpleParserTest.java index 70e0f3d397..e602a815c0 100644 --- a/src/test/java/com/google/cloud/spanner/pgadapter/statements/SimpleParserTest.java +++ b/src/test/java/com/google/cloud/spanner/pgadapter/statements/SimpleParserTest.java @@ -475,28 +475,27 @@ public void testParserTableOrIndexName() { @Test public void testReadArrayLiteral() { - assertEquals(ImmutableList.of(), SimpleParser.readArrayLiteral("{}", true, true)); - assertEquals(ImmutableList.of("foo"), SimpleParser.readArrayLiteral("{\"foo\"}", true, true)); + assertEquals(ImmutableList.of(), SimpleParser.readArrayLiteral("{}", true)); + assertEquals(ImmutableList.of("foo"), SimpleParser.readArrayLiteral("{\"foo\"}", true)); assertEquals( - ImmutableList.of("foo", "bar"), - SimpleParser.readArrayLiteral("{\"foo\", \"bar\"}", true, true)); + ImmutableList.of("foo", "bar"), SimpleParser.readArrayLiteral("{\"foo\", \"bar\"}", true)); assertEquals( Arrays.asList("foo", "bar", null), - SimpleParser.readArrayLiteral("{\"foo\", \"bar\", null}", true, true)); - assertEquals(ImmutableList.of("1", "2"), SimpleParser.readArrayLiteral("{1, 2}", false, true)); - assertEquals( - ImmutableList.of("1", "2"), SimpleParser.readArrayLiteral("{\"1\", \"2\"}", false, true)); + SimpleParser.readArrayLiteral("{\"foo\", \"bar\", null}", true)); + assertEquals(ImmutableList.of("1", "2"), SimpleParser.readArrayLiteral("{1, 2}", true)); + assertEquals(ImmutableList.of("1", "2"), SimpleParser.readArrayLiteral("{\"1\", \"2\"}", true)); assertEquals( ImmutableList.of("{\"foo\": \"bar\"}"), - SimpleParser.readArrayLiteral("{\"{\\\"foo\\\": \\\"bar\\\"}\"}", true, true)); + SimpleParser.readArrayLiteral("{\"{\\\"foo\\\": \\\"bar\\\"}\"}", true)); - assertThrows(PGException.class, () -> SimpleParser.readArrayLiteral("1, 2", false, true)); - assertThrows(PGException.class, () -> SimpleParser.readArrayLiteral("{1, 2", false, true)); - assertThrows(PGException.class, () -> SimpleParser.readArrayLiteral("1, 2}", false, true)); - assertThrows( - PGException.class, () -> SimpleParser.readArrayLiteral("{1, 2} extra token", false, true)); + assertThrows(PGException.class, () -> SimpleParser.readArrayLiteral("1, 2", true)); + assertThrows(PGException.class, () -> SimpleParser.readArrayLiteral("{1, 2", true)); + assertThrows(PGException.class, () -> SimpleParser.readArrayLiteral("1, 2}", true)); assertThrows( - PGException.class, - () -> SimpleParser.readArrayLiteral("{foo, bar}", /* mustBeQuoted = */ true, true)); + PGException.class, () -> SimpleParser.readArrayLiteral("{1, 2} extra token", true)); + + assertEquals(ImmutableList.of("foo", "bar"), SimpleParser.readArrayLiteral("{foo, bar}", true)); + assertEquals( + ImmutableList.of("foo 1", "bar 2"), SimpleParser.readArrayLiteral("{foo 1, bar 2}", true)); } }