/sdks/java/extensions/sql/src/test/java/org/apache/beam/sdk/extensions/sql/impl/parser/BeamDDLTest.java

https://github.com/apache/beam · Java · 240 lines · 189 code · 33 blank · 18 comment · 0 complexity · 51e21bc85231bf4647af79675a4c0dd7 MD5 · raw file

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.beam.sdk.extensions.sql.impl.parser;
  19. import static org.apache.beam.sdk.schemas.Schema.toSchema;
  20. import static org.junit.Assert.assertEquals;
  21. import static org.junit.Assert.assertNotNull;
  22. import static org.junit.Assert.assertNull;
  23. import com.alibaba.fastjson.JSONArray;
  24. import com.alibaba.fastjson.JSONObject;
  25. import java.util.stream.Stream;
  26. import org.apache.beam.sdk.extensions.sql.impl.BeamSqlEnv;
  27. import org.apache.beam.sdk.extensions.sql.impl.ParseException;
  28. import org.apache.beam.sdk.extensions.sql.impl.parser.impl.BeamSqlParserImpl;
  29. import org.apache.beam.sdk.extensions.sql.impl.utils.CalciteUtils;
  30. import org.apache.beam.sdk.extensions.sql.meta.Table;
  31. import org.apache.beam.sdk.extensions.sql.meta.provider.test.TestTableProvider;
  32. import org.apache.beam.sdk.options.PipelineOptionsFactory;
  33. import org.apache.beam.sdk.schemas.Schema;
  34. import org.junit.Test;
  35. /** UnitTest for {@link BeamSqlParserImpl}. */
  36. public class BeamDDLTest {
  37. @Test
  38. public void testParseCreateExternalTable_full() throws Exception {
  39. TestTableProvider tableProvider = new TestTableProvider();
  40. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  41. JSONObject properties = new JSONObject();
  42. JSONArray hello = new JSONArray();
  43. hello.add("james");
  44. hello.add("bond");
  45. properties.put("hello", hello);
  46. env.executeDdl(
  47. "CREATE EXTERNAL TABLE person (\n"
  48. + "id int COMMENT 'id', \n"
  49. + "name varchar COMMENT 'name') \n"
  50. + "TYPE 'text' \n"
  51. + "COMMENT 'person table' \n"
  52. + "LOCATION '/home/admin/person'\n"
  53. + "TBLPROPERTIES '{\"hello\": [\"james\", \"bond\"]}'");
  54. assertEquals(
  55. mockTable("person", "text", "person table", properties),
  56. tableProvider.getTables().get("person"));
  57. }
  58. @Test
  59. public void testParseCreateExternalTable_WithComplexFields() {
  60. TestTableProvider tableProvider = new TestTableProvider();
  61. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  62. env.executeDdl(
  63. "CREATE EXTERNAL TABLE PersonDetails"
  64. + " ( personInfo MAP<VARCHAR, ROW<field_1 INTEGER,field_2 VARCHAR>> , "
  65. + " additionalInfo ROW<field_0 TIMESTAMP,field_1 INTEGER,field_2 TINYINT> )"
  66. + " TYPE 'text'"
  67. + " LOCATION '/home/admin/person'");
  68. assertNotNull(tableProvider.getTables().get("PersonDetails"));
  69. }
  70. @Test(expected = ParseException.class)
  71. public void testParseCreateExternalTable_withoutType() throws Exception {
  72. BeamSqlEnv env = BeamSqlEnv.withTableProvider(new TestTableProvider());
  73. env.executeDdl(
  74. "CREATE EXTERNAL TABLE person (\n"
  75. + "id int COMMENT 'id', \n"
  76. + "name varchar COMMENT 'name') \n"
  77. + "COMMENT 'person table' \n"
  78. + "LOCATION '/home/admin/person'\n"
  79. + "TBLPROPERTIES '{\"hello\": [\"james\", \"bond\"]}'");
  80. }
  81. @Test(expected = ParseException.class)
  82. public void testParseCreateTable() throws Exception {
  83. BeamSqlEnv env = BeamSqlEnv.withTableProvider(new TestTableProvider());
  84. env.executeDdl(
  85. "CREATE TABLE person (\n"
  86. + "id int COMMENT 'id', \n"
  87. + "name varchar COMMENT 'name') \n"
  88. + "TYPE 'text' \n"
  89. + "COMMENT 'person table' \n"
  90. + "LOCATION '/home/admin/person'\n"
  91. + "TBLPROPERTIES '{\"hello\": [\"james\", \"bond\"]}'");
  92. }
  93. @Test
  94. public void testParseCreateExternalTable_withoutTableComment() throws Exception {
  95. TestTableProvider tableProvider = new TestTableProvider();
  96. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  97. JSONObject properties = new JSONObject();
  98. JSONArray hello = new JSONArray();
  99. hello.add("james");
  100. hello.add("bond");
  101. properties.put("hello", hello);
  102. env.executeDdl(
  103. "CREATE EXTERNAL TABLE person (\n"
  104. + "id int COMMENT 'id', \n"
  105. + "name varchar COMMENT 'name') \n"
  106. + "TYPE 'text' \n"
  107. + "LOCATION '/home/admin/person'\n"
  108. + "TBLPROPERTIES '{\"hello\": [\"james\", \"bond\"]}'");
  109. assertEquals(
  110. mockTable("person", "text", null, properties), tableProvider.getTables().get("person"));
  111. }
  112. @Test
  113. public void testParseCreateExternalTable_withoutTblProperties() throws Exception {
  114. TestTableProvider tableProvider = new TestTableProvider();
  115. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  116. env.executeDdl(
  117. "CREATE EXTERNAL TABLE person (\n"
  118. + "id int COMMENT 'id', \n"
  119. + "name varchar COMMENT 'name') \n"
  120. + "TYPE 'text' \n"
  121. + "COMMENT 'person table' \n"
  122. + "LOCATION '/home/admin/person'\n");
  123. assertEquals(
  124. mockTable("person", "text", "person table", new JSONObject()),
  125. tableProvider.getTables().get("person"));
  126. }
  127. @Test
  128. public void testParseCreateExternalTable_withoutLocation() throws Exception {
  129. TestTableProvider tableProvider = new TestTableProvider();
  130. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  131. env.executeDdl(
  132. "CREATE EXTERNAL TABLE person (\n"
  133. + "id int COMMENT 'id', \n"
  134. + "name varchar COMMENT 'name') \n"
  135. + "TYPE 'text' \n"
  136. + "COMMENT 'person table' \n");
  137. assertEquals(
  138. mockTable("person", "text", "person table", new JSONObject(), null),
  139. tableProvider.getTables().get("person"));
  140. }
  141. @Test
  142. public void testParseCreateExternalTable_minimal() throws Exception {
  143. TestTableProvider tableProvider = new TestTableProvider();
  144. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  145. env.executeDdl("CREATE EXTERNAL TABLE person (id INT) TYPE text");
  146. assertEquals(
  147. Table.builder()
  148. .name("person")
  149. .type("text")
  150. .schema(
  151. Stream.of(Schema.Field.of("id", CalciteUtils.INTEGER).withNullable(true))
  152. .collect(toSchema()))
  153. .properties(new JSONObject())
  154. .build(),
  155. tableProvider.getTables().get("person"));
  156. }
  157. @Test
  158. public void testParseCreateExternalTable_withDatabase() throws Exception {
  159. TestTableProvider rootProvider = new TestTableProvider();
  160. TestTableProvider testProvider = new TestTableProvider();
  161. BeamSqlEnv env =
  162. BeamSqlEnv.builder(rootProvider)
  163. .addSchema("test", testProvider)
  164. .setPipelineOptions(PipelineOptionsFactory.create())
  165. .build();
  166. assertNull(testProvider.getTables().get("person"));
  167. env.executeDdl("CREATE EXTERNAL TABLE test.person (id INT) TYPE text");
  168. assertNotNull(testProvider.getTables().get("person"));
  169. }
  170. @Test
  171. public void testParseDropTable() throws Exception {
  172. TestTableProvider tableProvider = new TestTableProvider();
  173. BeamSqlEnv env = BeamSqlEnv.withTableProvider(tableProvider);
  174. assertNull(tableProvider.getTables().get("person"));
  175. env.executeDdl(
  176. "CREATE EXTERNAL TABLE person (\n"
  177. + "id int COMMENT 'id', \n"
  178. + "name varchar COMMENT 'name') \n"
  179. + "TYPE 'text' \n"
  180. + "COMMENT 'person table' \n");
  181. assertNotNull(tableProvider.getTables().get("person"));
  182. env.executeDdl("drop table person");
  183. assertNull(tableProvider.getTables().get("person"));
  184. }
  185. private static Table mockTable(String name, String type, String comment, JSONObject properties) {
  186. return mockTable(name, type, comment, properties, "/home/admin/" + name);
  187. }
  188. private static Table mockTable(
  189. String name, String type, String comment, JSONObject properties, String location) {
  190. return Table.builder()
  191. .name(name)
  192. .type(type)
  193. .comment(comment)
  194. .location(location)
  195. .schema(
  196. Stream.of(
  197. Schema.Field.of("id", CalciteUtils.INTEGER)
  198. .withNullable(true)
  199. .withDescription("id"),
  200. Schema.Field.of("name", CalciteUtils.VARCHAR)
  201. .withNullable(true)
  202. .withDescription("name"))
  203. .collect(toSchema()))
  204. .properties(properties)
  205. .build();
  206. }
  207. }