diff --git a/core/src/main/java/org/apache/iceberg/view/ViewProperties.java b/core/src/main/java/org/apache/iceberg/view/ViewProperties.java new file mode 100644 index 000000000000..56dc73f5afd0 --- /dev/null +++ b/core/src/main/java/org/apache/iceberg/view/ViewProperties.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.iceberg.view; + +/** View properties that can be set during CREATE/REPLACE view or using updateProperties API. */ +public class ViewProperties { + public static final String COMMIT_NUM_RETRIES = "commit.retry.num-retries"; + public static final int COMMIT_NUM_RETRIES_DEFAULT = 4; + + public static final String COMMIT_MIN_RETRY_WAIT_MS = "commit.retry.min-wait-ms"; + public static final int COMMIT_MIN_RETRY_WAIT_MS_DEFAULT = 100; + + public static final String COMMIT_MAX_RETRY_WAIT_MS = "commit.retry.max-wait-ms"; + public static final int COMMIT_MAX_RETRY_WAIT_MS_DEFAULT = 60000; // 1 minute + + public static final String COMMIT_TOTAL_RETRY_TIME_MS = "commit.retry.total-timeout-ms"; + public static final int COMMIT_TOTAL_RETRY_TIME_MS_DEFAULT = 1800000; // 30 minutes + + public static final String VERSION_HISTORY_SIZE = "version.history.num-entries"; + public static final int VERSION_HISTORY_SIZE_DEFAULT = 10; + + public static final String TABLE_COMMENT = "comment"; + + private ViewProperties() {} +} diff --git a/core/src/test/java/org/apache/iceberg/util/TestJsonUtil.java b/core/src/test/java/org/apache/iceberg/util/TestJsonUtil.java deleted file mode 100644 index 8a769fccb9e2..000000000000 --- a/core/src/test/java/org/apache/iceberg/util/TestJsonUtil.java +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.iceberg.util; - -import com.fasterxml.jackson.core.JsonProcessingException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; -import org.assertj.core.api.Assertions; -import org.junit.Test; - -public class TestJsonUtil { - - @Test - public void get() throws JsonProcessingException { - Assertions.assertThatThrownBy(() -> JsonUtil.get("x", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing field: x"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.get("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing field: x"); - - Assertions.assertThat(JsonUtil.get("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}")).asText()) - .isEqualTo("23"); - } - - @Test - public void getInt() throws JsonProcessingException { - Assertions.assertThatThrownBy(() -> JsonUtil.getInt("x", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing int: x"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getInt("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to an integer value: x: null"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getInt("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to an integer value: x: \"23\""); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getInt("x", JsonUtil.mapper().readTree("{\"x\": 23.0}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to an integer value: x: 23.0"); - - Assertions.assertThat(JsonUtil.getInt("x", JsonUtil.mapper().readTree("{\"x\": 23}"))) - .isEqualTo(23); - } - - @Test - public void getIntOrNull() throws JsonProcessingException { - Assertions.assertThat(JsonUtil.getIntOrNull("x", JsonUtil.mapper().readTree("{}"))).isNull(); - Assertions.assertThat(JsonUtil.getIntOrNull("x", JsonUtil.mapper().readTree("{\"x\": 23}"))) - .isEqualTo(23); - Assertions.assertThat(JsonUtil.getIntOrNull("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isNull(); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getIntOrNull("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to an integer value: x: \"23\""); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getIntOrNull("x", JsonUtil.mapper().readTree("{\"x\": 23.0}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to an integer value: x: 23.0"); - } - - @Test - public void getLong() throws JsonProcessingException { - Assertions.assertThatThrownBy(() -> JsonUtil.getLong("x", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing long: x"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLong("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a long value: x: null"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLong("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a long value: x: \"23\""); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLong("x", JsonUtil.mapper().readTree("{\"x\": 23.0}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a long value: x: 23.0"); - - Assertions.assertThat(JsonUtil.getLong("x", JsonUtil.mapper().readTree("{\"x\": 23}"))) - .isEqualTo(23); - } - - @Test - public void getLongOrNull() throws JsonProcessingException { - Assertions.assertThat(JsonUtil.getLongOrNull("x", JsonUtil.mapper().readTree("{}"))).isNull(); - Assertions.assertThat(JsonUtil.getLongOrNull("x", JsonUtil.mapper().readTree("{\"x\": 23}"))) - .isEqualTo(23); - Assertions.assertThat(JsonUtil.getLongOrNull("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isNull(); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLongOrNull("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a long value: x: \"23\""); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLongOrNull("x", JsonUtil.mapper().readTree("{\"x\": 23.0}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a long value: x: 23.0"); - } - - @Test - public void getString() throws JsonProcessingException { - Assertions.assertThatThrownBy(() -> JsonUtil.getString("x", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing string: x"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getString("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a string value: x: null"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getString("x", JsonUtil.mapper().readTree("{\"x\": 23}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a string value: x: 23"); - - Assertions.assertThat(JsonUtil.getString("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isEqualTo("23"); - } - - @Test - public void getStringOrNull() throws JsonProcessingException { - Assertions.assertThat(JsonUtil.getStringOrNull("x", JsonUtil.mapper().readTree("{}"))).isNull(); - Assertions.assertThat( - JsonUtil.getStringOrNull("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isEqualTo("23"); - Assertions.assertThat( - JsonUtil.getStringOrNull("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isNull(); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringOrNull("x", JsonUtil.mapper().readTree("{\"x\": 23}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a string value: x: 23"); - } - - @Test - public void getBool() throws JsonProcessingException { - Assertions.assertThatThrownBy(() -> JsonUtil.getBool("x", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing boolean: x"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getBool("x", JsonUtil.mapper().readTree("{\"x\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a boolean value: x: null"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getBool("x", JsonUtil.mapper().readTree("{\"x\": \"23\"}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a boolean value: x: \"23\""); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getBool("x", JsonUtil.mapper().readTree("{\"x\": \"true\"}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a boolean value: x: \"true\""); - - Assertions.assertThat(JsonUtil.getBool("x", JsonUtil.mapper().readTree("{\"x\": true}"))) - .isTrue(); - Assertions.assertThat(JsonUtil.getBool("x", JsonUtil.mapper().readTree("{\"x\": false}"))) - .isFalse(); - } - - @Test - public void getIntegerList() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getIntegerList("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing list: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getIntegerList("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-array value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getIntegerList( - "items", JsonUtil.mapper().readTree("{\"items\": [13, \"23\"]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse integer from non-int value in items: \"23\""); - - List items = Arrays.asList(23, 45); - Assertions.assertThat( - JsonUtil.getIntegerList("items", JsonUtil.mapper().readTree("{\"items\": [23, 45]}"))) - .isEqualTo(items); - - String json = - JsonUtil.generate( - gen -> { - gen.writeStartObject(); - JsonUtil.writeIntegerArray("items", items, gen); - gen.writeEndObject(); - }, - false); - Assertions.assertThat(JsonUtil.getIntegerList("items", JsonUtil.mapper().readTree(json))) - .isEqualTo(items); - } - - @Test - public void getIntegerSet() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getIntegerSet("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing set: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getIntegerSet("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-array value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getIntegerSet( - "items", JsonUtil.mapper().readTree("{\"items\": [13, \"23\"]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse integer from non-int value in items: \"23\""); - - Assertions.assertThat( - JsonUtil.getIntegerSet("items", JsonUtil.mapper().readTree("{\"items\": [23, 45]}"))) - .containsExactlyElementsOf(Arrays.asList(23, 45)); - } - - @Test - public void getIntegerSetOrNull() throws JsonProcessingException { - Assertions.assertThat(JsonUtil.getIntegerSetOrNull("items", JsonUtil.mapper().readTree("{}"))) - .isNull(); - - Assertions.assertThat( - JsonUtil.getIntegerSetOrNull("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isNull(); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getIntegerSetOrNull( - "items", JsonUtil.mapper().readTree("{\"items\": [13, \"23\"]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse integer from non-int value in items: \"23\""); - - Assertions.assertThat( - JsonUtil.getIntegerSetOrNull( - "items", JsonUtil.mapper().readTree("{\"items\": [23, 45]}"))) - .containsExactlyElementsOf(Arrays.asList(23, 45)); - } - - @Test - public void getLongList() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getLongList("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing list: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLongList("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-array value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getLongList( - "items", JsonUtil.mapper().readTree("{\"items\": [13, \"23\"]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse long from non-long value in items: \"23\""); - - List items = Arrays.asList(23L, 45L); - Assertions.assertThat( - JsonUtil.getLongList("items", JsonUtil.mapper().readTree("{\"items\": [23, 45]}"))) - .isEqualTo(items); - - String json = - JsonUtil.generate( - gen -> { - gen.writeStartObject(); - JsonUtil.writeLongArray("items", items, gen); - gen.writeEndObject(); - }, - false); - Assertions.assertThat(JsonUtil.getLongList("items", JsonUtil.mapper().readTree(json))) - .isEqualTo(items); - } - - @Test - public void getLongSet() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getLongSet("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing set: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getLongSet("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-array value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getLongSet( - "items", JsonUtil.mapper().readTree("{\"items\": [13, \"23\"]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse long from non-long value in items: \"23\""); - - Assertions.assertThat( - JsonUtil.getLongSet("items", JsonUtil.mapper().readTree("{\"items\": [23, 45]}"))) - .containsExactlyElementsOf(Arrays.asList(23L, 45L)); - } - - @Test - public void getLongSetOrNull() throws JsonProcessingException { - Assertions.assertThat(JsonUtil.getLongSetOrNull("items", JsonUtil.mapper().readTree("{}"))) - .isNull(); - - Assertions.assertThat( - JsonUtil.getLongSetOrNull("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isNull(); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getLongSetOrNull( - "items", JsonUtil.mapper().readTree("{\"items\": [13, \"23\"]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse long from non-long value in items: \"23\""); - - Assertions.assertThat( - JsonUtil.getLongSetOrNull("items", JsonUtil.mapper().readTree("{\"items\": [23, 45]}"))) - .containsExactlyElementsOf(Arrays.asList(23L, 45L)); - } - - @Test - public void getStringList() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringList("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing list: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringList("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-array value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getStringList( - "items", JsonUtil.mapper().readTree("{\"items\": [\"23\", 45]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse string from non-text value in items: 45"); - - List items = Arrays.asList("23", "45"); - Assertions.assertThat( - JsonUtil.getStringList( - "items", JsonUtil.mapper().readTree("{\"items\": [\"23\", \"45\"]}"))) - .containsExactlyElementsOf(items); - - String json = - JsonUtil.generate( - gen -> { - gen.writeStartObject(); - JsonUtil.writeStringArray("items", items, gen); - gen.writeEndObject(); - }, - false); - Assertions.assertThat(JsonUtil.getStringList("items", JsonUtil.mapper().readTree(json))) - .isEqualTo(items); - } - - @Test - public void getStringListOrNull() throws JsonProcessingException { - Assertions.assertThat(JsonUtil.getStringListOrNull("items", JsonUtil.mapper().readTree("{}"))) - .isNull(); - - Assertions.assertThat( - JsonUtil.getStringListOrNull("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isNull(); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getStringListOrNull( - "items", JsonUtil.mapper().readTree("{\"items\": [\"23\", 45]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse string from non-text value in items: 45"); - - Assertions.assertThat( - JsonUtil.getStringListOrNull( - "items", JsonUtil.mapper().readTree("{\"items\": [\"23\", \"45\"]}"))) - .containsExactlyElementsOf(Arrays.asList("23", "45")); - } - - @Test - public void getStringSet() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringSet("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing set: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringSet("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-array value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getStringSet( - "items", JsonUtil.mapper().readTree("{\"items\": [\"23\", 45]}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse string from non-text value in items: 45"); - - Assertions.assertThat( - JsonUtil.getStringSet( - "items", JsonUtil.mapper().readTree("{\"items\": [\"23\", \"45\"]}"))) - .containsExactlyElementsOf(Arrays.asList("23", "45")); - } - - @Test - public void getStringMap() throws JsonProcessingException { - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringMap("items", JsonUtil.mapper().readTree("{}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse missing map: items"); - - Assertions.assertThatThrownBy( - () -> JsonUtil.getStringMap("items", JsonUtil.mapper().readTree("{\"items\": null}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse from non-object value: items: null"); - - Assertions.assertThatThrownBy( - () -> - JsonUtil.getStringMap( - "items", JsonUtil.mapper().readTree("{\"items\": {\"a\":\"23\", \"b\":45}}"))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Cannot parse to a string value: b: 45"); - - Map items = ImmutableMap.of("a", "23", "b", "45"); - Assertions.assertThat( - JsonUtil.getStringMap( - "items", JsonUtil.mapper().readTree("{\"items\": {\"a\":\"23\", \"b\":\"45\"}}"))) - .isEqualTo(items); - - String json = - JsonUtil.generate( - gen -> { - gen.writeStartObject(); - JsonUtil.writeStringMap("items", items, gen); - gen.writeEndObject(); - }, - false); - Assertions.assertThat(JsonUtil.getStringMap("items", JsonUtil.mapper().readTree(json))) - .isEqualTo(items); - } -} diff --git a/core/src/test/resources/ValidViewMetadata.json b/core/src/test/resources/ValidViewMetadata.json new file mode 100644 index 000000000000..972fd64d8489 --- /dev/null +++ b/core/src/test/resources/ValidViewMetadata.json @@ -0,0 +1,38 @@ +{ + "format-version": 1, + "location": "s3://bucket/test/location", + "properties": {}, + "current-schema-id": 1, + "schemas": [ + { + "type": "struct", + "schema-id": 1, + "fields": [ + { + "id": 1, + "name": "x", + "required": true, + "type": "long" + }, + { + "id": 2, + "name": "y", + "required": true, + "type": "long", + "doc": "comment" + }, + { + "id": 3, + "name": "z", + "required": true, + "type": "long" + } + ] + } + ], + "current-version-id": 2, + "versions": [ + {"version-id":1,"timestamp-ms":4353,"summary":{},"representations":[{"type":"sql","sql":"select 'foo' foo","dialect":"","default-catalog":"","default-namespace":[],"field-aliases":[],"field-comments":[], "schema-id":1}]}, + {"version-id":2,"timestamp-ms":5555,"summary":{},"representations":[{"type":"sql","sql":"select 1 id, 'abc' data","dialect":"","default-catalog":"","default-namespace":[],"field-aliases":[],"field-comments":[], "schema-id": 1}]}], + "version-log": [{"timestamp-ms":4353,"version-id":1},{"timestamp-ms":5555,"version-id":2}] +} \ No newline at end of file