Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2638307
Create ArrayToJsonFunction.java
wlei-llvm Mar 21, 2015
2c63494
Create ArrayToJsonFunctionTest.java
wlei-llvm Mar 21, 2015
241f4c3
Delete ArrayToJsonFunctionTest.java
wlei-llvm Jun 28, 2015
f66ba90
Create JsonFunctionTest.java
wlei-llvm Jun 28, 2015
7f2a6cf
PHOENIX-1661
wlei-llvm Jun 28, 2015
db5c9e1
Delete ArrayToJsonFunction.java
wlei-llvm Jun 28, 2015
a02b954
Rename ArrayToJsonFunction1.java to ArrayToJsonFunction.java
wlei-llvm Jun 28, 2015
eb76667
Update ArrayToJsonFunction.java
wlei-llvm Jun 28, 2015
6546bc5
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
6bb8b11
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
3782d70
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
5ff6152
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
d21c22b
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
541697d
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
7e0dbaf
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
331e09b
PHOENIX-1661 Implement built-in functions for JSON
wlei-llvm Jun 28, 2015
9f2c22d
Merge branch 'master' into json
Jun 29, 2015
1646b8a
Merge branch 'json'
Jun 29, 2015
c8eb37c
1 add apache license
Jun 30, 2015
d99e8b6
add apache license
Jul 1, 2015
684ed52
fix bugs
Jul 20, 2015
5c3359c
Merge pull request #2 from ictwanglei/master
wlei-llvm Jul 24, 2015
dfad294
add end2end test files
Jul 26, 2015
63f0d92
delete JsonFunctionTest.java
Jul 26, 2015
7d94b86
fix bugs
Jul 26, 2015
e7759f4
rename and add more testcase
Aug 4, 2015
1bb5829
add null json value test
Aug 19, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
/*
* 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 boolColumnIndex = 2;
stmt.setArray(boolColumnIndex , boolArray);
// byte array
Array byteArray = conn.createArrayOf("TINYINT", new Byte[] { 11, 22 });
int byteColumnIndex = 3;
stmt.setArray(byteColumnIndex, byteArray);
// double array
Array doubleArray = conn.createArrayOf("DOUBLE", new Double[] { 67.78, 78.89 });
int doubleColumnIndex = 4;
stmt.setArray(doubleColumnIndex, doubleArray);
// float array
Array floatArray = conn.createArrayOf("FLOAT", new Float[] { 12.23f, 45.56f });
int floatColumnIndex = 5;
stmt.setArray(floatColumnIndex, floatArray);
// int array
Array intArray = conn.createArrayOf("INTEGER", new Integer[] { 5555, 6666 });
int intColumnIndex = 6;
stmt.setArray(intColumnIndex, intArray);
// long array
Array longArray = conn.createArrayOf("BIGINT", new Long[] { 7777777L, 8888888L });
int longColumnIndex = 7;
stmt.setArray(longColumnIndex, longArray);
// short array
Array shortArray = conn.createArrayOf("SMALLINT", new Short[] { 333, 444 });
int shortColumnIndex = 8;
stmt.setArray(shortColumnIndex, shortArray);
// create character array
Array stringArray = conn.createArrayOf("VARCHAR", new String[] { "a", "b" });
int stringColumnIndex = 9;
stmt.setArray(stringColumnIndex, stringArray);
stmt.execute();
conn.commit();

stmt =
conn.prepareStatement("SELECT pk, " +
"array_to_json(boolean_array), " +
"array_to_json(byte_array), " +
"array_to_json(double_array), " +
"array_to_json(float_array), " +
"array_to_json(int_array), " +
"array_to_json(long_array), " +
"array_to_json(short_array)," +
"array_to_json(string_array) FROM "
+ TABLE_WITH_ALL_ARRAY_TYPES);

ResultSet rs = stmt.executeQuery();
assertTrue(rs.next());

assertEquals("valueOne", rs.getString(1));
assertArrayToJson(rs, boolColumnIndex , "[true,false]");
assertArrayToJson(rs, byteColumnIndex, "[11,22]");
assertArrayToJson(rs, doubleColumnIndex, "[67.78,78.89]");
assertArrayToJson(rs, floatColumnIndex, "[12.23,45.56]");
assertArrayToJson(rs, intColumnIndex, "[5555,6666]");
assertArrayToJson(rs, longColumnIndex, "[7777777,8888888]");
assertArrayToJson(rs, shortColumnIndex, "[333,444]");
assertArrayToJson(rs, stringColumnIndex, "[\"a\",\"b\"]");

} finally {
conn.close();
}

}

@Test
public void testArrayToJsonWithNullValueArray() throws Exception {
// create the table
String ddlStmt = "create table "
+ "TABLE_NULL_VALUE_ARRAY"
+ " (PK VARCHAR NOT NULL PRIMARY KEY,\n"
+ " NULL_VALUE_ARRAY varchar(100) array[2]"
+ ")";
createTestTable(getUrl(), ddlStmt);

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_NULL_VALUE_ARRAY"
+ "(PK, NULL_VALUE_ARRAY)\n"
+ "VALUES (?, ?)");

stmt.setString(1, "valueOne");

Array nullValueArray = conn.createArrayOf("VARCHAR", new String[] { null, null });
int nullValueIndex = 2;
stmt.setArray(nullValueIndex, nullValueArray);
stmt.execute();
conn.commit();

stmt =
conn.prepareStatement("SELECT PK, " +
"ARRAY_TO_JSON(NULL_VALUE_ARRAY) FROM "
+ "TABLE_NULL_VALUE_ARRAY");

ResultSet rs = stmt.executeQuery();
assertTrue(rs.next());

assertEquals("valueOne", rs.getString(1));
assertArrayToJson(rs, nullValueIndex, "[null,null]");

} finally {
conn.close();
}

}



private void assertArrayToJson(ResultSet rs, int arrayIndex, String expectedJson)
throws SQLException {
assertEquals("Json array data is not as expected.",expectedJson, rs.getString(arrayIndex));
}


private static void createTableWithAllArrayTypes(String url) throws SQLException {
String ddlStmt = "create table "
+ TABLE_WITH_ALL_ARRAY_TYPES
+ " (pk VARCHAR NOT NULL PRIMARY KEY,\n"
+ " boolean_array boolean array[2],\n"
+ " byte_array tinyint[2],\n"
+ " double_array double[2],\n"
+ " float_array float[2],\n"
+ " int_array integer[2],\n"
+ " long_array bigint[5],\n"
+ " short_array smallint[2],\n"
+ " string_array varchar(100) array[2]"
+ ")";
createTestTable(url, ddlStmt);
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
/*
* 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'";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JamesRTaylor the postgress implementation returns a SETOF json, while this returns a varchar array. Do you think this is OK?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ok because Phoenix does not have a SETOF.
When we move to calcite we may need to rethink this. We should see how Apache Drill handles this.

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,null,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[5];
strArr[0] = "1";
strArr[1] = "36.763";
strArr[2] = "null";
strArr[3] = "false";
strArr[4] = "\"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);
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 testJsonArrayElementsWithInvalidJsonInput() throws Exception {
Connection conn = getConnection();
String json = "{\"f1\":1,\"f2\":\"abc\"}";
String pk = "valueOne";
try {
populateJsonTable(conn, json, pk);

String selectQuery = "SELECT json_array_elements(col1) FROM testJson WHERE pk = 'valueOne'";

try {
PreparedStatement stmt = conn.prepareStatement(selectQuery);
ResultSet rs = stmt.executeQuery();
assertTrue(rs.next());
rs.getArray(1);
fail("The Json Node should be an array!");
} catch (SQLException sqe) {
assertEquals("SQL error code is not as expected.",
SQLExceptionCode.JSON_NODE_MISMATCH.getErrorCode(), sqe.getErrorCode());
assertEquals("SQL state is not expected.", "22001",
sqe.getSQLState());
}

} finally {
conn.close();
}
}


private void populateJsonTable(Connection conn, String json, String pk)
throws SQLException {
String ddl = "CREATE TABLE testJson"
+ " (pk VARCHAR NOT NULL PRIMARY KEY, " + "col1 json)";
createTestTable(getUrl(), ddl);

String query = "UPSERT INTO testJson(pk, col1) VALUES(?,?)";
PreparedStatement stmt = conn.prepareStatement(query);
stmt.setString(1, pk);
stmt.setString(2, json);
stmt.execute();
conn.commit();
}

private Connection getConnection() throws SQLException {
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
return conn;
}
}
Loading