[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/102#discussion_r36014571 --- Diff: phoenix-core/src/it/java/org/apache/phoenix/end2end/JsonArrayElementsFunctionIT.java --- @@ -0,0 +1,175 @@ +/* + * 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.phoenix.end2end; + +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.schema.types.PhoenixArray; +import org.apache.phoenix.util.PropertiesUtil; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.*; + +/** + * End to end test for {@link org.apache.phoenix.expression.function.JsonArrayElementsFunction}. + * + */ +public class JsonArrayElementsFunctionIT extends BaseHBaseManagedTimeIT { + +@Test +public void testJsonArrayElementsWithSameType() throws Exception { +Connection conn = getConnection(); + +try { +String json = [25.343,36.763,37.56,386.63]; +String pk = valueOne; + +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_elements(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +String[] strArr = new String[4]; +strArr[0] = 25.343; +strArr[1] = 36.763; +strArr[2] = 37.56; +strArr[3] = 386.63; +Array array = conn.createArrayOf(VARCHAR, strArr); +PhoenixArray resultArray = (PhoenixArray) rs.getArray(1); +assertEquals(Json array elements is not as expected., resultArray, +array); +assertFalse(rs.next()); + +} finally { +conn.close(); +} +} +@Test +public void testJsonArrayElementsWithDifferentDataTypes() throws Exception { +Connection conn = getConnection(); + +try { +String json = [1,36.763,false,\string\]; +String pk = valueOne; + +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_elements(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +String[] strArr = new String[4]; +strArr[0] = 1; +strArr[1] = 36.763; +strArr[2] = false; +strArr[3] = \string\; + +Array array = conn.createArrayOf(VARCHAR, strArr); +PhoenixArray resultArray = (PhoenixArray) rs.getArray(1); + +assertEquals(Json array elements is not as expected., resultArray, +array); +assertFalse(rs.next()); + +} finally { +conn.close(); +} +} +@Test +public void testJsonArrayElementsWithNestJson() throws Exception { +Connection conn = getConnection(); + +try { +String json = [1,[1,true,\string\]]; +String pk = valueOne; + +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_elements(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +String[] strArr = new String[2]; +strArr[0] = 1; +strArr[1] = [1,true,\string\]; +Array array = conn.createArrayOf(VARCHAR, strArr
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/102#discussion_r36014695 --- Diff: phoenix-core/src/it/java/org/apache/phoenix/end2end/JsonArrayLengthFunctionIT.java --- @@ -0,0 +1,177 @@ +/* + * 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.phoenix.end2end; + +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.*; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.expression.function.JsonArrayLengthFunction; +import org.apache.phoenix.schema.IllegalDataException; +import org.apache.phoenix.util.PropertiesUtil; +import org.junit.Test; + +/** + * End to end test for {@link JsonArrayLengthFunction}. + * + */ +public class JsonArrayLengthFunctionIT extends BaseHBaseManagedTimeIT { + + @Test + public void testJsonArrayLengthWithIntTypeInWhereClause() throws Exception { + Connection conn = getConnection(); + String json = [1,2,3]; + String pk = valueOne; + try { + populateJsonTable(conn, json, pk); + + String selectQuery = SELECT col1 FROM testJson WHERE json_array_length(col1) = 3; + PreparedStatement stmt = conn.prepareStatement(selectQuery); + ResultSet rs = stmt.executeQuery(); + assertTrue(rs.next()); + assertEquals(Json data is not as expected., json, + rs.getString(1)); + assertFalse(rs.next()); + + } finally { + conn.close(); + } + } + +@Test +public void testJsonArrayLengthWithDoubleType() throws Exception { +Connection conn = getConnection(); +String json = [1.23,2.34,3.56,54.3]; +String pk = valueOne; +try { +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_length(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +assertEquals(Json array length is not as expected., 4, +rs.getInt(1)); +assertFalse(rs.next()); + +} finally { +conn.close(); +} +} + +@Test +public void testJsonArrayLengthWithDifferentDataTypes() +throws Exception { +Connection conn = getConnection(); +String json = [1,2.3,true,\f1\,[\string\,3]]; +String pk = valueOne; +try { +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_length(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +assertEquals(Json array length is not as expected., +5, rs.getInt(1)); + +assertFalse(rs.next()); + +} finally { +conn.close(); +} +} +@Test +public void testJsonArrayLengthWithNestedJson() throws Exception { +Connection conn = getConnection(); +String json = [1,\string\,false,[1.23,[true,\ok\]]]; +String pk = valueOne; +try { +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT col1 FROM testJson WHERE json_array_length(col1) = 4
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/102#discussion_r36013361 --- Diff: phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToJsonFunctionIT.java --- @@ -0,0 +1,150 @@ +/* + * 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.phoenix.end2end; + +import static org.apache.phoenix.util.TestUtil.ROW1; +import static org.apache.phoenix.util.TestUtil.TABLE_WITH_ARRAY; +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.sql.*; +import java.util.Properties; +import org.apache.phoenix.expression.function.ArrayToJsonFunction; +import org.apache.phoenix.query.BaseTest; +import org.apache.phoenix.util.PhoenixRuntime; +import org.apache.phoenix.util.PropertiesUtil; +import org.junit.Test; + +/** + * End to end test for {@link org.apache.phoenix.expression.function.ArrayToJsonFunction}. + * + */ +public class ArrayToJsonFunctionIT extends BaseHBaseManagedTimeIT { +private static final String TABLE_WITH_ALL_ARRAY_TYPES = TABLE_WITH_ALL_ARRAY_TYPES; + +@Test +public void testArrayToJsonWithAllArrayTypes() throws Exception { +// create the table +createTableWithAllArrayTypes(getUrl()); + +Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); +Connection conn = DriverManager.getConnection(getUrl(), props); +conn.setAutoCommit(false); + +try{ +// populate the table with data +PreparedStatement stmt = +conn.prepareStatement(UPSERT INTO ++ TABLE_WITH_ALL_ARRAY_TYPES ++ (pk, BOOLEAN_ARRAY, BYTE_ARRAY, DOUBLE_ARRAY, FLOAT_ARRAY, INT_ARRAY, LONG_ARRAY, SHORT_ARRAY, STRING_ARRAY)\n ++ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)); + +stmt.setString(1, valueOne); + +// boolean array +Array boolArray = conn.createArrayOf(BOOLEAN, new Boolean[] { true,false }); +int boolIndex = 2; --- End diff -- Please rename boolIndex as boolColumnIndex and so for other index variables. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/102#discussion_r36014881 --- Diff: phoenix-core/src/it/java/org/apache/phoenix/end2end/JsonArrayLengthFunctionIT.java --- @@ -0,0 +1,177 @@ +/* + * 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.phoenix.end2end; + +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.*; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Properties; + +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.expression.function.JsonArrayLengthFunction; +import org.apache.phoenix.schema.IllegalDataException; +import org.apache.phoenix.util.PropertiesUtil; +import org.junit.Test; + +/** + * End to end test for {@link JsonArrayLengthFunction}. + * + */ +public class JsonArrayLengthFunctionIT extends BaseHBaseManagedTimeIT { + + @Test + public void testJsonArrayLengthWithIntTypeInWhereClause() throws Exception { + Connection conn = getConnection(); + String json = [1,2,3]; + String pk = valueOne; + try { + populateJsonTable(conn, json, pk); + + String selectQuery = SELECT col1 FROM testJson WHERE json_array_length(col1) = 3; + PreparedStatement stmt = conn.prepareStatement(selectQuery); + ResultSet rs = stmt.executeQuery(); + assertTrue(rs.next()); + assertEquals(Json data is not as expected., json, + rs.getString(1)); + assertFalse(rs.next()); + + } finally { + conn.close(); + } + } + +@Test +public void testJsonArrayLengthWithDoubleType() throws Exception { +Connection conn = getConnection(); +String json = [1.23,2.34,3.56,54.3]; +String pk = valueOne; +try { +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_length(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +assertEquals(Json array length is not as expected., 4, +rs.getInt(1)); +assertFalse(rs.next()); + +} finally { +conn.close(); +} +} + +@Test +public void testJsonArrayLengthWithDifferentDataTypes() +throws Exception { +Connection conn = getConnection(); +String json = [1,2.3,true,\f1\,[\string\,3]]; +String pk = valueOne; +try { +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_length(col1) FROM testJson WHERE pk = 'valueOne'; +PreparedStatement stmt = conn.prepareStatement(selectQuery); +ResultSet rs = stmt.executeQuery(); +assertTrue(rs.next()); +assertEquals(Json array length is not as expected., +5, rs.getInt(1)); + +assertFalse(rs.next()); + +} finally { +conn.close(); +} +} +@Test +public void testJsonArrayLengthWithNestedJson() throws Exception { +Connection conn = getConnection(); +String json = [1,\string\,false,[1.23,[true,\ok\]]]; +String pk = valueOne; +try { +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT col1 FROM testJson WHERE json_array_length(col1) = 4
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/102#discussion_r36013900 --- Diff: phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToJsonFunctionIT.java --- @@ -0,0 +1,150 @@ +/* + * 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.phoenix.end2end; + +import static org.apache.phoenix.util.TestUtil.ROW1; +import static org.apache.phoenix.util.TestUtil.TABLE_WITH_ARRAY; +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.sql.*; +import java.util.Properties; +import org.apache.phoenix.expression.function.ArrayToJsonFunction; +import org.apache.phoenix.query.BaseTest; +import org.apache.phoenix.util.PhoenixRuntime; +import org.apache.phoenix.util.PropertiesUtil; +import org.junit.Test; + +/** + * End to end test for {@link org.apache.phoenix.expression.function.ArrayToJsonFunction}. + * + */ +public class ArrayToJsonFunctionIT extends BaseHBaseManagedTimeIT { +private static final String TABLE_WITH_ALL_ARRAY_TYPES = TABLE_WITH_ALL_ARRAY_TYPES; + +@Test +public void testArrayToJsonWithAllArrayTypes() throws Exception { +// create the table +createTableWithAllArrayTypes(getUrl()); + +Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); +Connection conn = DriverManager.getConnection(getUrl(), props); +conn.setAutoCommit(false); + +try{ +// populate the table with data +PreparedStatement stmt = +conn.prepareStatement(UPSERT INTO ++ TABLE_WITH_ALL_ARRAY_TYPES ++ (pk, BOOLEAN_ARRAY, BYTE_ARRAY, DOUBLE_ARRAY, FLOAT_ARRAY, INT_ARRAY, LONG_ARRAY, SHORT_ARRAY, STRING_ARRAY)\n ++ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)); + +stmt.setString(1, valueOne); + +// boolean array +Array boolArray = conn.createArrayOf(BOOLEAN, new Boolean[] { true,false }); +int boolIndex = 2; +stmt.setArray(boolIndex, boolArray); +// byte array +Array byteArray = conn.createArrayOf(TINYINT, new Byte[] { 11, 22 }); +int byteIndex = 3; +stmt.setArray(byteIndex, byteArray); +// double array +Array doubleArray = conn.createArrayOf(DOUBLE, new Double[] { 67.78, 78.89 }); +int doubleIndex = 4; +stmt.setArray(doubleIndex, doubleArray); +// float array +Array floatArray = conn.createArrayOf(FLOAT, new Float[] { 12.23f, 45.56f }); +int floatIndex = 5; +stmt.setArray(floatIndex, floatArray); +// int array +Array intArray = conn.createArrayOf(INTEGER, new Integer[] { , }); +int intIndex = 6; +stmt.setArray(intIndex, intArray); +// long array +Array longArray = conn.createArrayOf(BIGINT, new Long[] { 777L, 888L }); +int longIndex = 7; +stmt.setArray(longIndex, longArray); +// short array +Array shortArray = conn.createArrayOf(SMALLINT, new Short[] { 333, 444 }); +int shortIndex = 8; +stmt.setArray(shortIndex, shortArray); +// create character array +Array stringArray = conn.createArrayOf(VARCHAR, new String[] { a, b }); +int stringIndex = 9; +stmt.setArray(stringIndex, stringArray); +stmt.execute(); +conn.commit(); + +stmt = +conn.prepareStatement(SELECT pk, + +array_to_json
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/102#discussion_r36014459 --- Diff: phoenix-core/src/it/java/org/apache/phoenix/end2end/JsonArrayElementsFunctionIT.java --- @@ -0,0 +1,175 @@ +/* + * 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.phoenix.end2end; + +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.schema.types.PhoenixArray; +import org.apache.phoenix.util.PropertiesUtil; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; +import static org.junit.Assert.*; + +/** + * End to end test for {@link org.apache.phoenix.expression.function.JsonArrayElementsFunction}. + * + */ +public class JsonArrayElementsFunctionIT extends BaseHBaseManagedTimeIT { + +@Test +public void testJsonArrayElementsWithSameType() throws Exception { +Connection conn = getConnection(); + +try { +String json = [25.343,36.763,37.56,386.63]; +String pk = valueOne; + +populateJsonTable(conn, json, pk); + +String selectQuery = SELECT json_array_elements(col1) FROM testJson WHERE pk = 'valueOne'; --- End diff -- @JamesRTaylor the postgress implementation returns a SETOF json, while this returns a varchar array. Do you think this is OK? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/93#discussion_r33425159 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,355 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.schema.EqualityNotSupportedException; +import org.apache.phoenix.schema.types.*; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/93#discussion_r33424657 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayToJsonFunction.java --- @@ -0,0 +1,87 @@ +package org.apache.phoenix.expression.function; + +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.parse.FunctionParseNode; +import org.apache.phoenix.schema.IllegalDataException; +import org.apache.phoenix.schema.SortOrder; +import org.apache.phoenix.schema.json.PhoenixJson; +import org.apache.phoenix.schema.tuple.Tuple; +import org.apache.phoenix.schema.types.*; +import org.apache.phoenix.util.ByteUtil; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + + +@FunctionParseNode.BuiltInFunction(name=ArrayToJsonFunction.NAME, args={ +@FunctionParseNode.Argument(allowedTypes={PVarchar.class})} ) +public class ArrayToJsonFunction extends ScalarFunction { +public static final String NAME = Array_To_Json; --- End diff -- Please use only capital letters for function name. I guess thats the general convention we are following for other functions though I dont know whether it has any functional significance or not. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/93#discussion_r33425152 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,355 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.schema.EqualityNotSupportedException; +import org.apache.phoenix.schema.types.*; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/93#discussion_r33424861 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,355 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.schema.EqualityNotSupportedException; +import org.apache.phoenix.schema.types.*; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/93#discussion_r33425136 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,355 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.schema.EqualityNotSupportedException; +import org.apache.phoenix.schema.types.*; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6
[GitHub] phoenix pull request: PHOENIX-1661 Implement built-in functions fo...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/93#discussion_r33425135 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,355 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.schema.EqualityNotSupportedException; +import org.apache.phoenix.schema.types.*; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6
[GitHub] phoenix pull request: PHOENIX-1938 Like operator should throw prop...
Github user AakashPradeep commented on the pull request: https://github.com/apache/phoenix/pull/81#issuecomment-104047363 As per the SQL specification, LIKE only works with String data type (http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt search for Like predicate) . If it has been set to PVarchar.isCoercible() that means anything which can be coerced to Varchar but is not varchar for example VarBinary and JSON, can also be used with Like. IMHO Like should only work with Varhcar and char datatype and throw illegal data type error with other datatype arguments. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-1938 Like operator should throw prop...
Github user AakashPradeep commented on the pull request: https://github.com/apache/phoenix/pull/81#issuecomment-104074791 Agreed, but then for all data type like JSON which is coercible to Varchar or Char but does not want to support LIKE will have to add an if statement. Do you think thats ok ? --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-1938 Like operator should throw prop...
Github user AakashPradeep commented on the pull request: https://github.com/apache/phoenix/pull/81#issuecomment-101011634 @JamesRTaylor and @twdsilva can you please review it. It is required for Json. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-1938 Like operator should throw prop...
GitHub user AakashPradeep opened a pull request: https://github.com/apache/phoenix/pull/81 PHOENIX-1938 Like operator should throw proper exception when it is used with data type other then Varcahr and Char LIKE operator should be supported only for Varchar and Char and it should throw SQLException with SQLExceptionCode.TYPE_NOT_SUPPORTED_FOR_OPERATOR for any other data type. Postgres specification : http://www.postgresql.org/docs/8.3/static/functions-matching.html Oracle specification: http://docs.oracle.com/cd/B12037_01/server.101/b10759/conditions016.htm @JamesRTaylor @twdsilva Can you please review this. You can merge this pull request into a Git repository by running: $ git pull https://github.com/AakashPradeep/phoenix bugfix Alternatively you can review and apply these changes as the patch at: https://github.com/apache/phoenix/pull/81.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #81 commit fd615a7c267e58b2b4a4a10c595c1aeababbdb72 Author: Aakash email2aak...@gmail.com Date: 2015-04-30T04:41:00Z PHOENIX-1938 Like operator should throw proper exception when it is used with data type other then Varcahr and Char commit 5b9d5d5d5bd7754da3e8023b5a005be2590f6abe Author: Aakash email2aak...@gmail.com Date: 2015-04-30T04:47:42Z PHOENIX-1938 Like operator should throw proper exception when it is used with data type other then Varcahr and Char commit ad04526922193c99314b91c9fe21abe2d8759035 Author: Aakash email2aak...@gmail.com Date: 2015-04-30T05:13:22Z PHOENIX-1938 Like operator should throw proper exception when it is used with data type other then Varcahr and Char- IT test --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29271341 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,252 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29276493 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,252 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29280570 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,252 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29280348 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,252 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on the pull request: https://github.com/apache/phoenix/pull/76#issuecomment-96815390 @twdsilva @JamesRTaylor I have made changes as per the comments. Please let me know if there is anything more. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29202428 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,255 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29202881 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,255 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29205807 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,255 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29201607 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,255 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29203436 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,255 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode rootNode; +/* + * input data has been stored as it is, since some data is lost when json parser runs, for + * example if a JSON object within the value contains the same key more than once then only last + * one is stored rest all of them are ignored, which will defy the contract of PJsonDataType of + * keeping user data as it is. + */ +private final String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getInstance(String jsonData) throws SQLException { +if (jsonData == null) { + return null; +} +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +JsonNode jsonNode = getRootJsonNode(jsonParser); +return new PhoenixJson(jsonNode, jsonData); +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +/** + * Returns the root of the resulting {@link JsonNode} tree. + */ +private static JsonNode getRootJsonNode(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +return objectMapper.readTree(jsonParser); +} finally { +jsonParser.close(); +} +} + +/* Default for unit testing */PhoenixJson(final JsonNode node, final String jsonData) { +Preconditions.checkNotNull(node, root node cannot be null for json); +this.rootNode = node; +this.jsonAsString = jsonData; +} + +/** + * Get {@link PhoenixJson} for a given json paths. For example : + * p + * code + * {f2:{f3:1},f4:{f5:99,f6:{f7:2}}}' + * /code + * p + * for this source json, if we want to know the json at path {'f4','f6'} it will return + * {@link PhoenixJson} object for json {f7:2}. It always returns the last key if same
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29108294 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,266 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode node; +private String jsonAsString; --- End diff -- Needs suggestions to decide whether json data should be cached as byte [] or String. byte[] --- If it is byte[] following methods would not involve any String to byte [] or byte [] to String conversion 1. toBytes(Object object, byte[] bytes, int offset) 2. toBytes(Object object) 3. toObject(byte[] bytes, int offset, int length, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) But for following, we require byte [] - String 1. toStringLiteral(Object o, Format formatter) And for toObject(Object object, @SuppressWarnings(rawtypes) PDataType actualType) if actualType is Varchar we require String - byte [] String - Where as in case of String, following methods will require String - byte [] 1. toBytes(Object object, byte[] bytes, int offset) 2. toBytes(Object object) 3. toObject(byte[] bytes, int offset, int length, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) No conversion required for toStringLiteral(Object o, Format formatter) and toObject(Object object, @SuppressWarnings(rawtypes) PDataType actualType) if actualType is Varchar. byte[] seems to be more efficient here but I am not sure which is most used method and will help in performance or not. @JamesRTaylor @twdsilva --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29096442 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,280 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode node; +private String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param data Buffer that contains data to parse + * @param offset Offset of the first data byte within buffer + * @param length Length of contents to parse within buffer + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(byte[] jsonData, int offset, int length) +throws SQLException { + +String jsonDataStr = Bytes.toString(jsonData, offset, length); +return getPhoenixJson(jsonDataStr); + +} + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(String jsonData) throws SQLException { +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +PhoenixJson phoenixJson = getPhoneixJson(jsonParser); +/* + * input data has been stored as it is, since some data is lost when json parser runs, + * for example if a JSON object within the value contains the same key more than once + * then only last one is stored rest all of them are ignored, which will defy the + * contract of PJsonDataType of keeping user data as it is. + */ +phoenixJson.setJsonAsString(jsonData); +return phoenixJson; +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +private static PhoenixJson getPhoneixJson(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +JsonNode rootNode = objectMapper.readTree(jsonParser); +PhoenixJson phoenixJson = new PhoenixJson(rootNode); +return phoenixJson
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29096324 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,280 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode node; +private String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param data Buffer that contains data to parse + * @param offset Offset of the first data byte within buffer + * @param length Length of contents to parse within buffer + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(byte[] jsonData, int offset, int length) +throws SQLException { + +String jsonDataStr = Bytes.toString(jsonData, offset, length); +return getPhoenixJson(jsonDataStr); + +} + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(String jsonData) throws SQLException { +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +PhoenixJson phoenixJson = getPhoneixJson(jsonParser); +/* + * input data has been stored as it is, since some data is lost when json parser runs, + * for example if a JSON object within the value contains the same key more than once + * then only last one is stored rest all of them are ignored, which will defy the + * contract of PJsonDataType of keeping user data as it is. + */ +phoenixJson.setJsonAsString(jsonData); +return phoenixJson; +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +private static PhoenixJson getPhoneixJson(JsonParser jsonParser) throws IOException, --- End diff -- Nice catch.. I will fix it. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29097031 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java --- @@ -1144,17 +1144,18 @@ public static PDataType fromLiteral(Object value) { return null; } for (PDataType type : PDataType.values()) { - if (type.isArrayType()) { -PhoenixArray arr = (PhoenixArray) value; -if ((type.getSqlType() == arr.baseType.sqlType + PDataType.ARRAY_TYPE_BASE) - type.getJavaClass().isInstance(value)) { - return type; -} - } else { -if (type.getJavaClass().isInstance(value)) { - return type; -} - } + if (type.isArrayType() type.getJavaClass().isInstance(value)) { --- End diff -- isInstance() is costly it has a native implementation, I will try to avoid it as much as possible. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29097048 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java --- @@ -1144,17 +1144,18 @@ public static PDataType fromLiteral(Object value) { return null; } for (PDataType type : PDataType.values()) { - if (type.isArrayType()) { -PhoenixArray arr = (PhoenixArray) value; -if ((type.getSqlType() == arr.baseType.sqlType + PDataType.ARRAY_TYPE_BASE) - type.getJavaClass().isInstance(value)) { - return type; -} - } else { -if (type.getJavaClass().isInstance(value)) { - return type; -} - } + if (type.isArrayType() type.getJavaClass().isInstance(value)) { --- End diff -- @twdsilva , your placement of isInstance() is good since in current case if it is of Array type but not compatible class then it will call isInstance() twice (once in if () + once in else part ) whereas in your case it will be called only once. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29096924 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,280 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode node; +private String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param data Buffer that contains data to parse + * @param offset Offset of the first data byte within buffer + * @param length Length of contents to parse within buffer + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(byte[] jsonData, int offset, int length) +throws SQLException { + +String jsonDataStr = Bytes.toString(jsonData, offset, length); +return getPhoenixJson(jsonDataStr); + +} + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(String jsonData) throws SQLException { +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +PhoenixJson phoenixJson = getPhoneixJson(jsonParser); +/* + * input data has been stored as it is, since some data is lost when json parser runs, + * for example if a JSON object within the value contains the same key more than once + * then only last one is stored rest all of them are ignored, which will defy the + * contract of PJsonDataType of keeping user data as it is. + */ +phoenixJson.setJsonAsString(jsonData); +return phoenixJson; +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +private static PhoenixJson getPhoneixJson(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +JsonNode rootNode = objectMapper.readTree(jsonParser); +PhoenixJson phoenixJson = new PhoenixJson(rootNode); +return phoenixJson
[GitHub] phoenix pull request: PHOENIX-628 Support native JSON data type
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/76#discussion_r29096515 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,280 @@ +/* + * 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.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; + +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson implements ComparablePhoenixJson { +private final JsonNode node; +private String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param data Buffer that contains data to parse + * @param offset Offset of the first data byte within buffer + * @param length Length of contents to parse within buffer + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(byte[] jsonData, int offset, int length) +throws SQLException { + +String jsonDataStr = Bytes.toString(jsonData, offset, length); +return getPhoenixJson(jsonDataStr); + +} + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link SQLException} if it is invalid with line number and character. + * @param jsonData Json data as {@link String}. + * @return {@link PhoenixJson}. + * @throws SQLException + */ +public static PhoenixJson getPhoenixJson(String jsonData) throws SQLException { +try { +JsonFactory jsonFactory = new JsonFactory(); +JsonParser jsonParser = jsonFactory.createJsonParser(jsonData); +PhoenixJson phoenixJson = getPhoneixJson(jsonParser); +/* + * input data has been stored as it is, since some data is lost when json parser runs, + * for example if a JSON object within the value contains the same key more than once + * then only last one is stored rest all of them are ignored, which will defy the + * contract of PJsonDataType of keeping user data as it is. + */ +phoenixJson.setJsonAsString(jsonData); +return phoenixJson; +} catch (IOException x) { +throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_JSON_DATA).setRootCause(x) +.setMessage(x.getMessage()).build().buildException(); +} + +} + +private static PhoenixJson getPhoneixJson(JsonParser jsonParser) throws IOException, +JsonProcessingException { +jsonParser.configure(Feature.ALLOW_COMMENTS, true); +ObjectMapper objectMapper = new ObjectMapper(); +try { +JsonNode rootNode = objectMapper.readTree(jsonParser); +PhoenixJson phoenixJson = new PhoenixJson(rootNode); +return phoenixJson
[GitHub] phoenix pull request: Support native JSON data type and json_extra...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/75#discussion_r28935794 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/json/PhoenixJson.java --- @@ -0,0 +1,216 @@ +package org.apache.phoenix.schema.json; + +import java.io.IOException; +import java.sql.SQLException; + +import org.apache.hadoop.hbase.util.Bytes; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParseException; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonParser.Feature; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ValueNode; + +import com.google.common.base.Preconditions; + +/** + * The {@link PhoenixJson} wraps json and uses Jackson library to parse and traverse the json. It + * should be used to represent the JSON data type and also should be used to parse Json data and + * read the value from it. It always conside the last value if same key exist more than once. + */ +public class PhoenixJson { +private final JsonNode node; +private String jsonAsString; + +/** + * Static Factory method to get an {@link PhoenixJson} object. It also validates the json and + * throws {@link JsonParseException} if it is invalid with line number and character, which + * should be wrapped in {@link SQLException} by caller. + * @param data Buffer that contains data to parse + * @param offset Offset of the first data byte within buffer + * @param length Length of contents to parse within buffer + * @return {@link PhoenixJson}. + * @throws JsonParseException + * @throws IOException + */ +public static PhoenixJson getPhoenixJson(byte[] jsonData, int offset, int length) +throws JsonParseException, IOException { --- End diff -- Nice suggestion, will make this change. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: Support native JSON data type and json_extra...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/75#discussion_r28935743 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java --- @@ -1144,17 +1144,18 @@ public static PDataType fromLiteral(Object value) { return null; } for (PDataType type : PDataType.values()) { - if (type.isArrayType()) { -PhoenixArray arr = (PhoenixArray) value; -if ((type.getSqlType() == arr.baseType.sqlType + PDataType.ARRAY_TYPE_BASE) - type.getJavaClass().isInstance(value)) { - return type; -} - } else { -if (type.getJavaClass().isInstance(value)) { - return type; -} - } + if (type.isArrayType() type.getJavaClass().isInstance(value)) { --- End diff -- I will fix the formatting error here. But it is required to check the isInstance() in first IF itself otherwise it throw ClassCastException. For any value whose data type ordinal is less than PhoenixArray will try to be type casted to PhoenixArray at 1148 which is wrong as it is iterated in the order of ordinal where PhoenixArray type will be iterated before PJsonDataType. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: Support native JSON data type and json_extra...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/75#discussion_r28935769 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/schema/types/PVarchar.java --- @@ -30,134 +31,145 @@ public class PVarchar extends PDataTypeString { --- End diff -- I will revert this. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: Support native JSON data type and json_extra...
Github user AakashPradeep commented on the pull request: https://github.com/apache/phoenix/pull/75#issuecomment-95399238 @JamesRTaylor Can you please review Phoenix Json. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: Support native JSON data type and json_extra...
GitHub user AakashPradeep opened a pull request: https://github.com/apache/phoenix/pull/75 Support native JSON data type and json_extract_path function PHOENIX-174... ...3 and PHOENIX-1710 You can merge this pull request into a Git repository by running: $ git pull https://github.com/AakashPradeep/phoenix json Alternatively you can review and apply these changes as the patch at: https://github.com/apache/phoenix/pull/75.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #75 commit bab8f40c745b0f3cfd28597d6938574f4ba91ea2 Author: Aakash aakash.prad...@salesforce.com Date: 2015-04-14T01:32:10Z Support native JSON data type and json_extract_path function PHOENIX-1743 and PHOENIX-1710 --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---
[GitHub] phoenix pull request: Support native JSON data type and json_extra...
Github user AakashPradeep commented on a diff in the pull request: https://github.com/apache/phoenix/pull/75#discussion_r28935112 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/expression/function/JsonExtractPathTextFunction.java --- @@ -0,0 +1,108 @@ +package org.apache.phoenix.expression.function; + +import java.sql.SQLException; +import java.util.List; + +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.phoenix.compile.KeyPart; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.parse.FunctionParseNode.Argument; +import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction; +import org.apache.phoenix.schema.IllegalDataException; +import org.apache.phoenix.schema.json.PhoenixJson; +import org.apache.phoenix.schema.tuple.Tuple; +import org.apache.phoenix.schema.types.PDataType; +import org.apache.phoenix.schema.types.PJsonDataType; +import org.apache.phoenix.schema.types.PVarchar; +import org.apache.phoenix.schema.types.PVarcharArray; +import org.apache.phoenix.schema.types.PhoenixArray; +import org.apache.phoenix.util.ByteUtil; + +@BuiltInFunction(name = JsonExtractPathTextFunction.NAME, args = { +@Argument(allowedTypes = { PJsonDataType.class }), +@Argument(allowedTypes = { PVarcharArray.class }) }) +public class JsonExtractPathTextFunction extends ScalarFunction { +public static final String NAME = JSON_EXTRACT_PATH_TEXT; + +public JsonExtractPathTextFunction() { +super(); +} + +public JsonExtractPathTextFunction(ListExpression children) { +super(children); +} + +@Override +public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { +Expression jsonExpression = this.children.get(0); +if (!jsonExpression.evaluate(tuple, ptr)) { +return false; +} +if (ptr.getLength() == 0) { +return false; +} +PhoenixJson phoenixJson = +(PhoenixJson) PJsonDataType.INSTANCE.toObject(ptr.get(), ptr.getOffset(), +ptr.getLength()); + +Expression jsonPathArrayExpression = children.get(1); +if (!jsonPathArrayExpression.evaluate(tuple, ptr)) { +return false; +} + +if (ptr.getLength() == 0) { +return false; +} + +PhoenixArray phoenixArray = (PhoenixArray) PVarcharArray.INSTANCE.toObject(ptr); +try { +String[] jsonPaths = (String[]) phoenixArray.getArray(); +PhoenixJson phoenixJson2 = phoenixJson.getNullablePhoenixJson(jsonPaths); +if (phoenixJson2 == null) { +ptr.set(ByteUtil.EMPTY_BYTE_ARRAY); +} else { +byte[] json = PVarchar.INSTANCE.toBytes(phoenixJson2.serializeToString()); +ptr.set(json); +} + +} catch (SQLException sqe) { +new IllegalDataException(new SQLExceptionInfo.Builder(SQLExceptionCode.ILLEGAL_DATA) --- End diff -- Yeah I missed that. I will add them. --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---