[
https://issues.apache.org/jira/browse/PHOENIX-628?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14512621#comment-14512621
]
ASF GitHub Bot commented on PHOENIX-628:
----------------------------------------
Github user JamesRTaylor commented on a diff in the pull request:
https://github.com/apache/phoenix/pull/76#discussion_r29102541
--- Diff:
phoenix-core/src/main/java/org/apache/phoenix/schema/types/PJson.java ---
@@ -0,0 +1,223 @@
+/*
+ * 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.types;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.text.Format;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.schema.IllegalDataException;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.json.PhoenixJson;
+import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.StringUtil;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * <p>
+ * A Phoenix data type to represent JSON. The json data type stores an
exact copy of the input text,
+ * which processing functions must reparse on each execution. Because the
json type stores an exact
+ * copy of the input text, it will preserve semantically-insignificant
white space between tokens,
+ * as well as the order of keys within JSON objects. Also, if a JSON
object within the value
+ * contains the same key more than once, all the key/value pairs are kept.
It stores the data as
+ * string in single column of HBase and it has same data size limit as
Phoenix's Varchar.
+ * <p>
+ * JSON data types are for storing JSON (JavaScript Object Notation) data,
as specified in RFC 7159.
+ * Such data can also be stored as text, but the JSON data types have the
advantage of enforcing
+ * that each stored value is valid according to the JSON rules.
+ */
+public class PJson extends PDataType<String> {
+
+ public static final PJson INSTANCE = new PJson();
+
+ PJson() {
+ super("JSON", Types.OTHER, PhoenixJson.class, null, 48);
+ }
+
+ @Override
+ public int toBytes(Object object, byte[] bytes, int offset) {
+
+ if (object == null) {
+ return 0;
+ }
+ byte[] b = toBytes(object);
+ System.arraycopy(b, 0, bytes, offset, b.length);
+ return b.length;
+
+ }
+
+ @Override
+ public byte[] toBytes(Object object) {
+ if (object == null) {
+ return ByteUtil.EMPTY_BYTE_ARRAY;
+ }
+ PhoenixJson phoenixJson = (PhoenixJson) object;
+ return PVarchar.INSTANCE.toBytes(phoenixJson.toString());
+ }
+
+ @Override
+ public Object toObject(byte[] bytes, int offset, int length,
+ @SuppressWarnings("rawtypes") PDataType actualType, SortOrder
sortOrder,
+ Integer maxLength, Integer scale) {
+
+ if (!actualType.isCoercibleTo(this)) {
+ throwConstraintViolationException(actualType, this);
+ }
+ if (length == 0) {
+ return null;
+ }
+ return getPhoenixJson(bytes, offset, length);
+
+ }
+
+ @Override
+ public Object toObject(Object object, @SuppressWarnings("rawtypes")
PDataType actualType) {
+ if (object == null) {
+ return null;
+ }
+ if (equalsAny(actualType, PJson.INSTANCE)) {
+ return object;
+ }
+ if (equalsAny(actualType, PVarchar.INSTANCE)) {
+ return getJsonFromVarchar(object, actualType);
+ }
+ return throwConstraintViolationException(actualType, this);
+ }
+
+ @Override
+ public boolean isCoercibleTo(@SuppressWarnings("rawtypes") PDataType
targetType) {
+ return equalsAny(targetType, this, PVarchar.INSTANCE);
+
+ }
+
+ @Override
+ public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object
value,
+ @SuppressWarnings("rawtypes") PDataType srcType, Integer
maxLength, Integer scale,
+ Integer desiredMaxLength, Integer desiredScale) {
+ return PVarchar.INSTANCE.isSizeCompatible(ptr, value, srcType,
maxLength, scale,
+ desiredMaxLength, desiredScale);
+ }
+
+ @Override
+ public boolean isFixedWidth() {
+ return false;
+ }
+
+ @Override
+ public int estimateByteSize(Object o) {
+ PhoenixJson phoenixJson = (PhoenixJson) o;
+ return phoenixJson.estimateByteSize();
+ }
+
+ @Override
+ public Integer getByteSize() {
+ return null;
+ }
+
+ @Override
+ public int compareTo(Object lhs, Object rhs,
@SuppressWarnings("rawtypes") PDataType rhsType) {
+ if (PJson.INSTANCE != rhsType) {
+ throwConstraintViolationException(rhsType, this);
+ }
+ PhoenixJson phoenixJsonLHS = (PhoenixJson) lhs;
+ PhoenixJson phoenixJsonRHS = (PhoenixJson) rhs;
+ return phoenixJsonLHS.compareTo(phoenixJsonRHS);
+ }
+
+ @Override
+ public Object toObject(String value) {
+ return getPhoenixJson(value);
+ }
+
+ @Override
+ public boolean isBytesComparableWith(@SuppressWarnings("rawtypes")
PDataType otherType) {
+ return otherType == PJson.INSTANCE || otherType ==
PVarchar.INSTANCE;
+ }
+
+ @Override
+ public String toStringLiteral(Object o, Format formatter) {
+ if (o == null) {
+ return StringUtil.EMPTY_STRING;
+ }
+ PhoenixJson phoenixJson = (PhoenixJson) o;
+ return PVarchar.INSTANCE.toStringLiteral(phoenixJson.toString(),
formatter);
+ }
+
+ @Override
+ public Object getSampleValue(Integer maxLength, Integer arrayLength) {
+ Preconditions.checkArgument(maxLength == null || maxLength >= 0);
+
+ char[] key = new char[4];
+ char[] value = new char[4];
+ int length = maxLength != null ? maxLength : 1;
+ if (length > (key.length + value.length)) {
+ key = new char[length + 2];
+ value = new char[length - key.length];
+ }
+ int j = 1;
+ key[0] = '"';
+ key[j++] = 'k';
+ for (int i = 2; i < key.length - 1; i++) {
+ key[j++] = (char) ('0' + RANDOM.get().nextInt(Byte.MAX_VALUE)
% 10);
+ }
+ key[j] = '"';
+
+ int k = 1;
+ value[0] = '"';
+ value[k++] = 'v';
+ for (int i = 2; i < value.length - 1; i++) {
+ value[k++] = (char) ('0' +
RANDOM.get().nextInt(Byte.MAX_VALUE) % 10);
+ }
+ value[k] = '"';
+ StringBuilder sbr = new StringBuilder();
+ sbr.append("{").append(key).append(":").append(value).append("}");
+
+ byte[] bytes = Bytes.toBytes(sbr.toString());
+ return getPhoenixJson(bytes, 0, bytes.length);
--- End diff --
Get rid of this method: getPhoenixJson(byte[], offset, length). Instead,
just have getPhoenixJson(String), since you're relying on having a String.
Converting from a String -> byte[] -> String which is a waste.
> Support native JSON data type
> -----------------------------
>
> Key: PHOENIX-628
> URL: https://issues.apache.org/jira/browse/PHOENIX-628
> Project: Phoenix
> Issue Type: Task
> Affects Versions: 4.4.0
> Reporter: James Taylor
> Assignee: Aakash Pradeep
> Labels: JSON, Java, SQL
> Fix For: 4.4.0
>
>
> MongoDB and PostGres do some interesting things with JSON. We should look at
> adding similar support. For a detailed description, see JSONB support in
> Postgres:
> http://www.craigkerstiens.com/2014/03/24/Postgres-9.4-Looking-up
> http://www.depesz.com/2014/03/25/waiting-for-9-4-introduce-jsonb-a-structured-format-for-storing-json/
> http://michael.otacoo.com/postgresql-2/manipulating-jsonb-data-with-key-unique/
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)