Unstable Postgresql C Function - sql

I'm running PG 9.5 on Win 10 64-bit. I'm compiling C under VS 2016.
I am forming a function that will evolve into a somewhat complex beast. To test out my initial efforts, the function accepts an array of int4 (this works fine and the code for processing it is not shown here). The function then grabs a few rows from a table, pushes the values into a FIFO, then pulls them out and renders the results. This approach is strategic to how the function will operate when complete.
The function works fine on first call, then throws this on any further calls:
ERROR: cache lookup failed for type 0 SQL state: XX000
I have no idea what is causing this.
However, sometimes it doesn't throw an error but executes without end.
Here is my code as lean as I can get it for question purposes:
PG:
CREATE TABLE md_key
(
id serial NOT NULL PRIMARY KEY,
pid int4 NOT NULL,
key integer NOT NULL,
vals int4[]
);
…
CREATE OR REPLACE FUNCTION md_key_query(int4[])
RETURNS TABLE (
id int4,
vals int4[]) AS E'\RoctPG', --abreviated for question
'md_key_query'
LANGUAGE c IMMUTABLE STRICT;
…
select * from md_key_query(array[1,2,3,4]::int4[])
C:
PG_FUNCTION_INFO_V1(md_key_query);
typedef struct
{
Datum id;
Datum vals;
} MdKeyNode;
typedef struct fifoAry
{
MdKeyNode nodes[32];
struct fifoAry *next;
int32 readpos;
int32 writepos;
} FifoAry;
typedef struct
{
FifoAry *fifo;
FifoAry *tail;
FifoAry *head;
uint32 nodescount;
Datum *retvals[2];
bool *retnulls[2];
} CtxArgs;
inline void push(CtxArgs *args, Datum id, Datum vals)
{
if (args->head->writepos == 32)
args->head = args->head->next = (FifoAry*)palloc0(sizeof(FifoAry));
MdKeyNode *node = &(args->head->nodes[args->head->writepos++]);
node->id = id;
node->vals = vals;
args->nodescount++;
}
inline MdKeyNode* pop(CtxArgs *args)
{
// if (!args->nodescount)
// return NULL;
if (args->tail->readpos == 32)
args->tail = args->tail->next;
args->nodescount--;
return &(args->tail->nodes[args->tail->readpos++]);
}
// use STRICT in the caller wrapper to ensure a null isn't passed in
PGMODULEEXPORT Datum md_key_query(PG_FUNCTION_ARGS)
{
uint32 i;
FuncCallContext *funcctx;
HeapTuple tuple;
MdKeyNode *node;
CtxArgs *args;
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
MemoryContext oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
Datum *in_datums;
bool *in_nulls;
bool fieldNull;
SPITupleTable *tuptable = SPI_tuptable;
int32 ret;
uint32 proc;
if (get_call_result_type(fcinfo, NULL, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("function returning record called in context that cannot accept type record")));
deconstruct_array(a, INT4OID, 4, true, 'i', &in_datums, &in_nulls, &ret);
if (!ret)
PG_RETURN_NULL();
(SPI_connect();
// initialize and set the cross-call structure
funcctx->user_fctx = args = (CtxArgs*)palloc0(sizeof(CtxArgs));
args->fifo = args->tail = args->head = (FifoAry*)palloc0(sizeof(FifoAry));
args->retvals = (Datum*)palloc(sizeof(Datum) * 2);
args->retnulls = (bool*)palloc0(sizeof(bool) * 2);
BlessTupleDesc(funcctx->tuple_desc);
// do some work here
// this is simply a test to see if this function is behaving as expected
ret = SPI_execute("select id, vals from public.md_key where vals is not null limit 64", true, 0);
if (ret <= 0)
ereport(ERROR, (errcode(ERRCODE_SQL_ROUTINE_EXCEPTION), errmsg("could not execute SQL")));
proc = SPI_processed;
if (proc > 0)
{
TupleDesc tupdesc = SPI_tuptable->tupdesc;
SPITupleTable *tuptable = SPI_tuptable;
for (i = 0; i < proc; i++)
{
tuple = tuptable->vals[i];
push(args, SPI_getbinval(tuple, tupdesc, 1, &fieldNull), SPI_getbinval(tuple, tupdesc, 2, &fieldNull));
}
}
SPI_finish();
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
args = funcctx->user_fctx;
if (args->nodescount > 0)
{
node = pop(args);
args->retvals[0] = node->id;
args->retvals[1] = node->vals;
tuple = heap_form_tuple(funcctx->tuple_desc, args->retvals, args->retnulls);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
}
else
{
SRF_RETURN_DONE(funcctx);
}
}

Fixed it. Moved one command as shown here:
{
// function is unstable if this is put earlier
SPI_finish();
SRF_RETURN_DONE(funcctx);
}

Related

Implementing qsort in Objective-C

I'm trying to use qsort to sort a C array in descending order based on what this website is suggesting.
Here is the relevant code:
int x = 3;
- (IBAction)CaptureButton:(id)sender
{
x++;
if (x % 3 == 1)
{
int areas[detectedBlobs.size()];
for (int i = 0; i < detectedBlobs.size(); i++)
{
areas[i] = detectedBlobs[i].getWidth() * detectedBlobs[i].getHeight();
}
int compareInts(void const *item1, void const *item2)
{ // first error
int const *int1 = item1;
int const *int2 = item2;
return (*int2 - *int1);
}
qsort(areas, detectedBlobs.size(), sizeof(int), compareInts); // second error
}
}
Here are the two errors I'm getting:
First error:
Function definition is not allowed here
Second error:
Use of undeclared identifier 'compareInts'
If I cannot define the comparator (compareInts) function here, where do I have to define it? Also, how can I get the qsort function to recognize the comparator?
Objective-C does not allow function definitions inside methods. Move compareInts outside of the method, and make it static to hide from other translation units:
static int compareInts(const void* item1, const void* item2) {
const int* int1 = (const int*)item1;
const int* int2 = (const int*)item2;
return (*int2 - *int1);
}
- (IBAction)CaptureButton:(id)sender {
x++;
if (x % 3 == 1) {
int areas[detectedBlobs.size()];
for (int i = 0; i < detectedBlobs.size(); i++) {
areas[i] = detectedBlobs[i].getWidth() * detectedBlobs[i].getHeight();
}
qsort(areas, detectedBlobs.size(), sizeof(int), compareInts);
}
}

Is there a way to generate 2D stretched mesh using CGAL?

I currently use CGAL to generate 2D Delaunay triangulation.One of the mesh control parameter is the maximum length of the triangle edge. The examples suggests that this parameter is a constant. I would like to know how this parameter be made function of some thing else, for example spatial location.
I think Delaunay meshing with variable density is not directly supported by CGAL although you could mesh your regions independently. Alternatively you may have a look at: http://www.geom.at/advanced-mesh-generation/ where I have implemented that as a callback function.
It doesn't look like CGAL provides an example of this but they machinery is all there. The details get a little complicated since the objects that control if triangles need to be refined also have to understand the priority under which triangles get refined.
To do this, I copied Delaunay_mesh_size_criteria_2 to create a new class (Delaunay_mesh_user_criteria_2) that has a spatially varying sizing field. Buried in the class is a function (user_sizing_field) that can be implemented with a varying size field based on location. The code below compares the size of the longest edge of the triangle to the minimum of the sizing field at the three vertices, but you could use a size at the barycenter or circumcenter or even send the entire triangle to the sizing function if you have a good way to compute the smallest allowable size on the triangle altogether.
This is a starting point, although a better solution would,
refactor some things to avoid so much duplication with with existing Delaunay_mesh_size_criteria,
allow the user to pass in the sizing function as an argument to the criteria object, and
be shipped with CGAL.
template <class CDT>
class Delaunay_mesh_user_criteria_2 :
public virtual Delaunay_mesh_criteria_2<CDT>
{
protected:
typedef typename CDT::Geom_traits Geom_traits;
double sizebound;
public:
typedef Delaunay_mesh_criteria_2<CDT> Base;
Delaunay_mesh_user_criteria_2(const double aspect_bound = 0.125,
const Geom_traits& traits = Geom_traits())
: Base(aspect_bound, traits){}
// first: squared_minimum_sine
// second: size
struct Quality : public std::pair<double, double>
{
typedef std::pair<double, double> Base;
Quality() : Base() {};
Quality(double _sine, double _size) : Base(_sine, _size) {}
const double& size() const { return second; }
const double& sine() const { return first; }
// q1<q2 means q1 is prioritised over q2
// ( q1 == *this, q2 == q )
bool operator<(const Quality& q) const
{
if( size() > 1 )
if( q.size() > 1 )
return ( size() > q.size() );
else
return true; // *this is big but not q
else
if( q.size() > 1 )
return false; // q is big but not *this
return( sine() < q.sine() );
}
std::ostream& operator<<(std::ostream& out) const
{
return out << "(size=" << size()
<< ", sine=" << sine() << ")";
}
};
class Is_bad: public Base::Is_bad
{
public:
typedef typename Base::Is_bad::Point_2 Point_2;
Is_bad(const double aspect_bound,
const Geom_traits& traits)
: Base::Is_bad(aspect_bound, traits) {}
Mesh_2::Face_badness operator()(const Quality q) const
{
if( q.size() > 1 )
return Mesh_2::IMPERATIVELY_BAD;
if( q.sine() < this->B )
return Mesh_2::BAD;
else
return Mesh_2::NOT_BAD;
}
double user_sizing_function(const Point_2 p) const
{
// IMPLEMENT YOUR CUSTOM SIZING FUNCTION HERE.
// BUT MAKE SURE THIS RETURNS SOMETHING LARGER
// THAN ZERO TO ALLOW THE ALGORITHM TO TERMINATE
return std::abs(p.x()) + .025;
}
Mesh_2::Face_badness operator()(const typename CDT::Face_handle& fh,
Quality& q) const
{
typedef typename CDT::Geom_traits Geom_traits;
typedef typename Geom_traits::Compute_area_2 Compute_area_2;
typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance_2;
Geom_traits traits; /** #warning traits with data!! */
Compute_squared_distance_2 squared_distance =
traits.compute_squared_distance_2_object();
const Point_2& pa = fh->vertex(0)->point();
const Point_2& pb = fh->vertex(1)->point();
const Point_2& pc = fh->vertex(2)->point();
double size_bound = std::min(std::min(user_sizing_function(pa),
user_sizing_function(pb)),
user_sizing_function(pc));
double
a = CGAL::to_double(squared_distance(pb, pc)),
b = CGAL::to_double(squared_distance(pc, pa)),
c = CGAL::to_double(squared_distance(pa, pb));
double max_sq_length; // squared max edge length
double second_max_sq_length;
if(a<b)
{
if(b<c) {
max_sq_length = c;
second_max_sq_length = b;
}
else { // c<=b
max_sq_length = b;
second_max_sq_length = ( a < c ? c : a );
}
}
else // b<=a
{
if(a<c) {
max_sq_length = c;
second_max_sq_length = a;
}
else { // c<=a
max_sq_length = a;
second_max_sq_length = ( b < c ? c : b );
}
}
q.second = 0;
q.second = max_sq_length / (size_bound*size_bound);
// normalized by size bound to deal
// with size field
if( q.size() > 1 )
{
q.first = 1; // (do not compute sine)
return Mesh_2::IMPERATIVELY_BAD;
}
Compute_area_2 area_2 = traits.compute_area_2_object();
double area = 2*CGAL::to_double(area_2(pa, pb, pc));
q.first = (area * area) / (max_sq_length * second_max_sq_length); // (sine)
if( q.sine() < this->B )
return Mesh_2::BAD;
else
return Mesh_2::NOT_BAD;
}
};
Is_bad is_bad_object() const
{ return Is_bad(this->bound(), this->traits /* from the bad class */); }
};
I am also interested for variable mesh criteria on the domaine with CGAL. I have found an alternative many years ago : https://www.cs.cmu.edu/~quake/triangle.html
But i am still interested to do the same things with CGAL ... I don't know if it is possible ...

I can't figure out how to call a variable from another method

I am am trying to call a variable in another method to my array.
var Com = the difficulty for the game. But the method below I'm trying to call the var Com, for: var c = Com.GetChoice();
Not sure why I can not figure out how to call it.
public object SetDiff()
{
Console.WriteLine("Enter difficulty #: (1 = Easy, 2 = Normal, 3 = Impossible)");
var diff = Console.ReadLine();
int mode;
int.TryParse(diff, out mode);
if (mode == 1)
{
Console.Clear();
var Com = new Easy();
return Com;
}
if (mode == 2)
{
Console.Clear();
var Com = new Medium();
return Com;
}
if (mode == 3)
{
Console.Clear();
var Com = new Hard();
return Com;
}
else
{
Console.WriteLine("That is not a valid input.");
return SetDiff();
}
} // Apparently you can't set variables in a switch.
public int[] FaceOff(int num)
{
int PlayerWin = 0;
int ComWin = 0;
int Tie = num + 1;
// TODO : Get rid of TIES!
for (int i = 0; i < num; i++)
{
var p = p1.GetChoice();
var c = Com.GetChoice();
You have many different options:
Pass as parameter
public int[] FaceOff(int num, int Com){...}
make a "global" variable
private int Com;
I would also recommend you to learn OOP (Object Orientated Programming) basics.

Whole Structure is being replaced with the last pointer Value

In my program I have used an array of pointers as a structure variable to get first name and second name from the user.
The following is my function call statement:
ret_val = update_person(&ptr_person[person_index],f_name,s_name);
where ptr_person[SIZE] is a pointer variable and f_name and s_name are character array variables.
The following is my function definition where name_ret is int:
name_ret update_person(person_name_et **person,char *first_arg,char *second_arg)
{
int val = SUCCESS, val1 = SUCCESS,val2= SUCCESS;
int f_len = sizeof(first_arg);
int s_len = sizeof(second_arg);
val2 = remove_newline(first_arg);
val1 = remove_newline(second_arg);
val = allocate_person(person, f_len, s_len);
if((val && val1) == SUCCESS)
{
(*person)->first_name = first_arg;
(*person)->second_name = second_arg;
return SUCCESS;
}
else
{
return FAILURE;
}
}
The problem in the code is it works fine at the instance but when the function is called next iteration the ptr_Person[0] is replaced with ptr_person[1] and if we have 5 instances then all the 5 variables are replaced by the last values.

Get varient array from VC++ dll to vb.net application

I have to get the Features array in vb.net application. How this can be done. This is a function in VC++ .
STDMETHODIMP CclsLicense::FeatureList(VARIANT* Features,BSTR HostName, VARIANT_BOOL *ret){
USES_CONVERSION;
int status = 0;
int iCount = 0;
int nLicenseFeatures = 0;
char **featureList = NULL; // List of features
// Safe Array
SAFEARRAYBOUND bound[1];
SAFEARRAY *safeArray = NULL; // A Safe array for VB
CComVariant *pBstr = NULL; // Array of BSTR Value
// Initialize the return value
*ret = VARIANT_FALSE;
nLicenseFeatures = 0;
featureList = new char*[MAX_FEATURES];
for (i=0;i<4;i++)
{
featureList[nLicenseFeatures]=array[i];
nLicenseFeatures++;
}
// Array starts at 0 and has the number of features as elements
bound[0].lLbound = 0;
bound[0].cElements = nLicenseFeatures;
// Initialize Array
if((safeArray = ::SafeArrayCreate( VT_VARIANT, 1, bound)) == NULL)
return E_FAIL;
::VariantClear(Features);
Features->vt = VT_VARIANT | VT_ARRAY;
Features->parray = safeArray;
//use direct access to data
if(FAILED(hr = ::SafeArrayAccessData(safeArray, (void HUGEP**)&pBstr)) || pBstr == NULL)
return hr;
iCount = 0;
while( featureList[iCount] != NULL )
{
// Add to Array
if(pBstr[iCount].bstrVal != NULL)
{
::SysFreeString(pBstr[iCount].bstrVal);
pBstr[iCount].bstrVal = NULL;
}
if(featureList[iCount] == NULL)
pBstr[iCount].bstrVal = ::SysAllocString(OLESTR("")); //imposible
else
pBstr[iCount].bstrVal = ::SysAllocString(T2OLE(featureList[iCount]));
pBstr[iCount].vt = VT_BSTR;
// Increment counter
iCount++;
}
// Release Array
::SafeArrayUnaccessData(safeArray);
*ret = VARIANT_TRUE;
return S_OK;
}
Vb.Net function to get the list of features
Public Shared Function FeatureList(ByVal strLicensePath As String)
Dim features(10) As String
Try
m_objUTSLicense = CreateObject("dll name")
Call m_objUTSLicense.FeatureList(features, "192.168.1.3")
Catch ex As Exception
End Try
Dim i As Integer
Dim size As Integer = features.Length
For i = 0 To size - 1
MessageBox.Show(features(i))
Next
End Function
When i am trying this code, getting the error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt"
I can't test this without your whole project, but you might try declaring a member variable (rather than a local) so that you can apply the necessary marshalling attribute. Something like:
Imports System.Runtime.InteropServices
<MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_BSTR)>
Private features As System.Array