commit 9f3d18d74903323d0cee581bef0d2c25253c9c83
Author: Daniel Farina <daniel@heroku.com>
Date:   Fri Apr 25 16:11:49 2014 -0700

    Fix off-by-one in variadic .execute handling

diff --git a/expected/varparam.out b/expected/varparam.out
index 9064fc7..cb9e229 100644
--- a/expected/varparam.out
+++ b/expected/varparam.out
@@ -12,3 +12,12 @@ do language plv8 $$
 $$;
 INFO:  pg_class
 INFO:  pg_index
+-- Show variadic argument handling
+do language plv8 $$
+   plv8.elog(INFO, JSON.stringify(plv8.execute("SELECT $1", 1)));
+   plv8.elog(INFO, JSON.stringify(plv8.execute("SELECT $1", [1])));
+   plv8.elog(INFO, JSON.stringify(plv8.execute("SELECT $1 a, $2 b", 1, 2)));
+$$;
+INFO:  [{"?column?":"1"}]
+INFO:  [{"?column?":"1"}]
+INFO:  [{"a":"1","b":"2"}]
diff --git a/plv8_func.cc b/plv8_func.cc
index 898ae5b..9426236 100644
--- a/plv8_func.cc
+++ b/plv8_func.cc
@@ -434,12 +434,12 @@ plv8_execute_params(const char *sql, Handle<Array> params)
 }
 
 static Handle<Array>
-convertArgsToArray(const Arguments &args, int start)
+convertArgsToArray(const Arguments &args, int start, int downshift)
 {
 	Local<Array> result = Array::New(args.Length() - start);
 	for (int i = start; i < args.Length(); i++)
 	{
-		result->Set(i, args[i]);
+		result->Set(i - downshift, args[i]);
 	}
 	return result;
 }
@@ -463,7 +463,7 @@ plv8_Execute(const Arguments &args)
 		if (args[1]->IsArray())
 			params = Handle<Array>::Cast(args[1]);
 		else /* Consume trailing elements as an array. */
-			params = convertArgsToArray(args, 1);
+			params = convertArgsToArray(args, 1, 1);
 	}
 
 	int				nparam = params.IsEmpty() ? 0 : params->Length();
@@ -508,7 +508,7 @@ plv8_Prepare(const Arguments &args)
 		if (args[1]->IsArray())
 			array = Handle<Array>::Cast(args[1]);
 		else /* Consume trailing elements as an array. */
-			array = convertArgsToArray(args, 1);
+			array = convertArgsToArray(args, 1, 0);
 		arraylen = array->Length();
 		types = (Oid *) palloc(sizeof(Oid) * arraylen);
 	}
@@ -591,7 +591,7 @@ plv8_PlanCursor(const Arguments &args)
 		if (args[0]->IsArray())
 			params = Handle<Array>::Cast(args[0]);
 		else
-			params = convertArgsToArray(args, 0);
+			params = convertArgsToArray(args, 0, 0);
 		nparam = params->Length();
 	}
 
@@ -703,7 +703,7 @@ plv8_PlanExecute(const Arguments &args)
 		if (args[0]->IsArray())
 			params = Handle<Array>::Cast(args[0]);
 		else
-			params = convertArgsToArray(args, 0);
+			params = convertArgsToArray(args, 0, 0);
 		nparam = params->Length();
 	}
 
diff --git a/sql/varparam.sql b/sql/varparam.sql
index cc3420c..fc3c9d2 100644
--- a/sql/varparam.sql
+++ b/sql/varparam.sql
@@ -10,3 +10,10 @@ do language plv8 $$
   cur.close();
   plan.free();
 $$;
+
+-- Show variadic argument handling
+do language plv8 $$
+   plv8.elog(INFO, JSON.stringify(plv8.execute("SELECT $1", 1)));
+   plv8.elog(INFO, JSON.stringify(plv8.execute("SELECT $1", [1])));
+   plv8.elog(INFO, JSON.stringify(plv8.execute("SELECT $1 a, $2 b", 1, 2)));
+$$;
