In VoltDB, How to store NULL in column when i pass empty string as parameter? - voltdb

Currently, When I pass an empty string in VoltDB Stored Procedure parameter, It stores as an empty string.
Is there any way to store NULL when I pass an empty string as a parameter(Just Like Oracle)?

In VoltDB, empty strings are not the same thing as NULL. Oracle is the only database I know that considers these equal. You can simply pass NULL into a VoltDB stored procedure if you wish to store NULL.
If you want an empty string to be stored as NULL, I think the best way to do this would be a conditional statement in some java stored procedure code. If the input is "", then store null. Like so:
public class Example extends VoltProcedure {
public final SQLStmt sql = new SQLStmt(
"INSERT INTO t (col1, col2) VALUES (?,?);");
public VoltTable[] run(long id, String val) throws VoltAbortException {
if (val.equals("")) {
val = null;
}
voltQueueSQL( sql, id, val );
return voltExecuteSQL();
}
}

Related

Extension method .ToJsv() from ServiceStack.Text ignores null values in collections

My test class:
public class TestA
{
public IEnumerable<string> Collection { get; set; }
}
When I call extension method .ToJsv() from ServiceStack.Text on TestA object with property Collection which is an array with some null values, the result does not contain null values. Even setting JsConfig.IncludeNullValues = true; does not bring the solution.
Test code:
var obj = new TestA { Collection = new[] { "T", null } };
var result = obj.ToJsv(); //here I get {Collection:[T,]} instead of {Collection:[T,null]}
Thanks for any suggestions.
Given its format JSV can’t serialize null values as they’d be indistinguishable from the ‘null’ literal string so it’s lack of a value is what indicates a property is null, but that’s no something that’s you’ll be able to rely on if you want to send null items in a collection in which case you’d need to special casing like maintaining which items are null in a different property or you’d need to use a different serializer.

Correct Syntax for Static Method Parameter in ExpressionEvaluatingSqlParameterSourceFactory

What is the correct syntax for a string expression meant to reference a call to a static function, when passed as a parameter to ExpressionEvaluatingSqlParameterSourceFactory?
As an example, I have a static function that returns a java.util.Date within a utility class:
public class DateTimeUtils {
private DateTimeUtils() {throw new IllegalStateException("Utility class");}
public static Date currentDeliveryDate() {
ZonedDateTime today = ZonedDateTime.now(ZoneOffset.UTC);
return new DateTime(
today.getYear(),
today.getMonthValue(),
today.getDayOfMonth(),
5,
0,
0)
.toDate();
}
I want to use the result of that function as a SQL parameter. The SQL is along the lines of
select zip
from delivery_status
where delivery_date = :deliverydate
And setting the parameter goes a little something like this:
public SqlParameterSourceFactory sourceFactory() {
ExpressionEvaluatingSqlParameterSourceFactory sourceFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
Map<String, String> params = new HashMap<>();
params.put("deliverydate", "#T(com.acme.util.DateTimeUtils).currentDeliveryDate()");
sourceFactory.setParameterExpressions(params);
return sourceFactory;
}
I've tried variations with/without T, pound sign, parenthesis, and fully qualified name, but I keep getting
org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter 'deliverydate': No value registered for key 'deliverydate'
at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:355)
Can one of you help me with the correct incantation?
Cheers, y'all.
Must work like this:
"T(com.acme.util.DateTimeUtils).currentDeliveryDate()"
No pound sign before T operator.

How to remove null data from JavaPairRDD

I am getting the Hbase data and trying to do a spark job on it. My table has around 70k rows and each row has a column 'type', which can have the values:post,comment or reply. Based on the type, I want to take out different Pair RDDs like shown below(for post).
JavaPairRDD<ImmutableBytesWritable, FlumePost> postPairRDD = hBaseRDD.mapToPair(
new PairFunction<Tuple2<ImmutableBytesWritable, Result>, ImmutableBytesWritable, FlumePost>() {
private static final long serialVersionUID = 1L;
public Tuple2<ImmutableBytesWritable, FlumePost> call(Tuple2<ImmutableBytesWritable, Result> arg0)
throws Exception {
FlumePost flumePost = new FlumePost();
ImmutableBytesWritable key = arg0._1;
Result result = arg0._2;
String type = Bytes.toString(result.getValue(Bytes.toBytes("cf"), Bytes.toBytes("t")));
if (type.equals("post")) {
return new Tuple2<ImmutableBytesWritable, FlumePost>(key, flumePost);
} else {
return null;
}
}
}).distinct();
Problem here is, For all the rows with type other than post I have to send null value which is undesirable. And iteration goes on for 70k times for all the three types, wasting the cycles. So my first question is:
1) What is the efficient way to do this?
So now after getting 70k results I put the distinct() method to remove the duplication of null values. So I end up having one null value object in it. I expect 20327 results but I get 20328.
2) Is there a way to remove this null entry from the pair RDD?
You can use the filter operation on the RDD.
Simply call:
.filter(new Function<Tuple2<ImmutableBytesWritable, FlumePost>, Boolean>() {
#Override
public Boolean call(Tuple2<ImmutableBytesWritable, FlumePost> v1) throws Exception {
return v1 != null;
}
})
before calling distinct() to filter out the nulls.

TableServiceContext and strongly typed table name

I have a DocumentDataServiceContext derived from TableServiceContext. Inside that class I have the following method:
public DataServiceQuery<Document> Documents
{
get
{
return this.CreateQuery<Document>("Documents");
}
}
Is there a way to get rid of the string constant passed to CreateQuery and instead obtain the table name used by CloudTableClient.CreateTablesFromModel(typeof(DocumentDataServiceContext))?
No. At the end of the day, the CreateQuery() must have the table name to query against. You can of course use convention or reflection to derive what that table name will be in another method, but at some point a string must be passed to CreateQuery.
public DataServiceQuery<T> CreateQueryByConvention<T>()
{
return this.CreateQuery<T>(typeof(T).ToString());
}

Rename fields in SubSonic select statement

Is there a way to rename fields when executing a select statement in SubSonic? I am using the ExecuteTypedList<MyClass> method to fill my List<MyClass> object but the properties of MyClass are not all the same as the column names from the DB table. In SQL I can do select col1 as 'FirstColumn', col2 as 'SecondColumn' from MyTable, is there a way to do something similar in SubSonic?
I believe Alias's are only available for aggregate columns.
You could just add properties of the same names as your columns to your class or a partial and map them to the properties you do use ala calculated field:
public class Songs
{
private string _songTitle;
public string SongTitle {
get { return _songTitle; }
set { _songTitle = value; }
}
public string SongName {
get { return _songTitle; }
set { _songTitle = value; }
}
}
I had the same need the other day, and added the functionality to my local copy of SubSonic. I've just submitted it a patch for it attached to this issue. Applying the patch will let you write a query like
new Select(Table1.IdColumn.AliasAs("table1ID"),
Table2.IdColumn.AliasAs("table2ID"))
.From(Table1.Schema)
.InnerJoin(Table2.Table1IdColumn, Table1.IDColumn);

Resources