PgMex


________        ______  ___            
___  __ \______ ___   |/  /________  __
__  /_/ /_  __ `/_  /|_/ /_  _ \_  |/_/
_  ____/_  /_/ /_  /  / / /  __/_>  <  
/_/     _\__, / /_/  /_/  \___//_/|_|  
        /____/                         



PgMex is a high-performance PostgreSQL client library for Matlab that enables a Matlab-based application to communicate with PostgreSQL database in the Matlab native way by passing data in a form of matrices, multi-dimensional arrays and structures. The library is written in pure C which gives a significant performance boost for both small and data-heavy database requests. Both Windows and Linux platforms are supported.

Key features

PgMex has the following key features:

We'll show you sample code on this pane!

API Overview

The library contains of a single package pgmex with a single function pgmexec designed for execution of various commands like connecting to a database, executing SQL queries on PostgreSQL server etc. The first input to pgmexec is always a command name with a few command-specific input parameters to follow.

import com.allied.pgmex.pgmexec;
%% connect to db
dbConn=com.allied.pgmex.pgmexec('connect','host=<myHos> user=<myUser> port=<myPort> password=<myPassword> dbname=<myDB>')
%% create schema and table
pgmexec('exec',dbConn,'CREATE SCHEMA IF NOT EXISTS demo');
pgmexec('exec',dbConn,'DROP TABLE IF EXISTS demo.demo_table');
pgResult=pgmexec('exec',dbConn,['CREATE TABLE IF NOT EXISTS demo.demo_table ('...
    't_date date,'...
    'exp_name varchar(40),'...
    'exp_conf xml,'...
    'exp_t_vec timestamp[],'...
    'exp_col_name_vec name[],'...
    'exp_res_mat float8[])'])% pgResult=uint64(3740775088)
%% get status of execution result (all is successful)
pgmexec('resultStatus',pgResult)% ans = 1
pgmexec('cmdStatus',pgResult)% ans= 'CREATE TABLE'
%% clear result
pgmexec('clear',pgResult)
%% insert the first tuple into the table and get it as text
%% create parameters structure
pgParam=pgmexec('paramCreate',dbConn)% pgParam =uint64(3843492816)
%% put values of parameters
pgmexec('putf',pgParam,...
    '%date %varchar %xml %timestamp[]@ %name[]@ %float8[]',...
    datenum('1-Dec-2016'),'Experiment #1',...
    ['<model type="struct" ><param1 type="double" >1</param1>'...
    '<param2 type="boolean" >false</param2></model>'],...
    datenum({'0:00:00';'0:00:10';'0:01:30'}),{'res1','res2'},...
    struct('valueMat',{[NaN 2.4;-2 Inf;0 NaN]},...
    'isNullMat',{[true false;false false;true false]},...
    'isValueNull',false));
% insert the correspoding tuple into the table
pgmexec('paramExec',dbConn,pgParam,...
    'INSERT INTO demo.demo_table values ($1, $2, $3, $4, $5, $6)');
% reset parameters once again
pgmexec('paramreset',pgParam)
% put new values of parameters
pgmexec('putf',pgParam,...
    '%date %varchar %xml %timestamp[]@ %name[]@ %float8[]',...
    datenum('3-Dec-2016'),'Experiment #2',[...
    '<model type="struct" ><param1 type="double" >NaN</param1>'...
    '   <param2 type="boolean" >false</param2></model>'],...
    datenum({'0:00:40';'0:02:30'}),{'res1','res2','res3'},...
    struct('valueMat',{[]},'isNullMat',{logical([])},...
    'isValueNull',{true}));
% insert one more tupole into the table
pgmexec('paramExec',dbConn,pgParam,...
    'INSERT INTO demo.demo_table values ($1, $2, $3, $4, $5, $6)');
% clear the parameters as they are not necesssary
pgmexec('paramClear',pgParam)
%% get results as binary
pgResult=pgmexec('exec',dbConn,'SELECT * FROM  demo.demo_table')
% pgResult=uint64(3849610544)
%
%% check pgResult
pgmexec('binaryTuples',pgResult)% ans=true - binary result
pgmexec('resultStatus',pgResult) %ans=2 (TUPLES_OK)
pgmexec('cmdStatus',pgResult)% ans='SELECT 2'
pgmexec('cmdTuples',pgResult)% ans='2'
pgmexec('nFields',pgResult)% ans=6
pgmexec('nTuples',pgResult)% ans=2
%% extract results
% get vector of experiment dates
STDate=pgmexec('getf',pgResult,'#date','t_date')
% STDate = struct with fields:
%          valueVec: [2?1 double]
%         isNullVec: [2?1 logical]
%    isValueNullVec: [2?1 logical]
%
tDateVec=STDate.valueVec
%
% tDateVec =[736666;736667]
%
% get names of experiments
SExpName=pgmexec('getf',pgResult,'%varchar',1)
% SExpName = struct with fields:
%           valueVec: {2?1 cell}
%          isNullVec: [2?1 logical]
%     isValueNullVec: [2?1 logical]
%
expNameCVec=SExpName.valueVec
% expNameCVec ={'Experiment #1','Experiment #2'}
%
% get results of experiments
[SExpTVec, SExpCol, SExpRes]=pgmexec('getf',pgResult,...
    '#timestamp[]@ #name[]@ #float8[]',...
    'exp_t_vec','exp_col_name_vec','exp_res_mat')
%
% SExpTVec, SExpCol, SExpRes are structures with fields:
%           valueVec: {2?1 cell}
%          isNullVec: {2?1 cell}
%     isValueNullVec: [2?1 logical]
%
% SExpTVec.valueVec={...
%    [736330;736330.000115741;736330.001041667];
%    [736330.000462963;736330.001736111]};
%
% SExpCol.valueVec={{'res1';'res2'};{'res1';'res2';'res3'}}
% SExpCol.isNullVec={[false;false];[false;false;false]}
% SExpCol.isValueNullVec=[false;false]
%
% SExpRes.valueVec={[0 2.4;-2 Inf;0 NaN];[]}
% SExpRes.isNullVec={[true false;false false;true false];logical.empty(0,0)}
% SExpRes.isValueNullVec=[false;true]
%
%% clear results
pgmexec('clear',pgResult)

Pointer arguments:

Some input and output arguments, are pointers to C structures, such as PGconnect . Matlab type for these arguments depends on the architecture of the implementation: uint32 for 32-bit or uint64 for 64-bit. These pointers often provide a handle for dynamically-allocated resources that should be freed when they are no longer needed. Free resources with special commands, such as clear and finish .

Field specification strings:

Commands putf and getf use field specification strings that essentially represent codecs for converting betwen PostgreSQL data Matlab data for specific pairs of types. The following table covers all Postgres-Matlab type pairs supported by PgMex .

PGMEX Postgres Matlab
int2 smallint int16
int4 integer int32
int8 bigint int64
float4 real single
float8 double precision double
numeric numeric char [1,N]
bool boolean logical
varchar varchar char [1,N]
text text char [1,N]
bpchar char char [1,N]
name name char [1,N]
xml xml char [1,N]
json json char [1,N]
bytea bytea uint8 [1,N]
serbytea bytea any type&ast;
serbytea_wn bytea any type&ast;
date date datenum
time time datenum
timetz timetz datenum
timestamp timestamp datenum
timestamptz timestamptz datenum

If ’@’ is added at the end of a type spec, then if the original value is not of a variable-length type, the value will be transformed to a column vector [N,1] ( getf ) or a 1D array ( putf ), regardless of the dimensions of the original value.

An empty array must have the dimensions [0,0] when it is given as an argument to putf . When an empty (zero-dimensional) array is read from the database, the resulting Matlab array also has the dimensions [0,0].

Variable-length inputs and outputs are string types, such as varchar, and byte array types, such as bytea. Scalar values of variable-length types are stored in row vectors, and arrays of variable-length types are stored in cell arrays. For instance, a [2,2] array of varchar may be given as {'foo','bar';'baz','qux'} .

serbytea and serbytea_wn type specs serve to store any Matlab variable as a byte array. The serialization and deserialization are performed in putf and getf respectively. The corresponding Postgres type is bytea for scalars and bytea[] for arrays. As with other variable-length types, arrays of variables should be packaged in cell arrays. When serbytea_wn type spec is used, putf always expects a special structure with NULL specifiers on input (see documentation for putf below). serbytea is used to put “naked” values, i.e. any structure will be interpreted as a Matlab variable to be serialized as is. For getf the specs serbytea and serbytea_wn are equivalent.

Date and time inputs and outputs are Matlab datenums (doubles). Since datenums do not store time zone information, time zone for timetz and timestamptz values is assumed to be UTC. The schema part of the type spec for PgMex types is pgmex , whereas the schema for standard types is pg_catalog . However, it is not necessary to specify the pgmex schema in the field spec string.

Exceptions: The first (component) part of PgMex exception identifiers is PgMex , followed by the function name and error mnemonic.

Connection Control

connect

connect opens a new database connection

INPUT:

OUTPUT:

 %% Example:
 dbConn=com.allied.pgmex.pgmexec('connect','dbname=test user=postgres');

finish

finish closes the connection to the server. Also frees memory used by the PGconn object.

com.allied.pgmex.pgmexec('finish',dbConn)

INPUT:

regular:

reset

reset resets the communication channel to the server.

 com.allied.pgmex.pgmexec('reset',dbConn)

INPUT:

regular:

DESCRIPTION:

This function will close the connection to the server and attempt to re-establish a new connection to the same server, using all the same parameters previously used. This might be useful for error recovery if a working connection is lost.

Connection Status

db

db returns the database name of the connection.

 dbName=com.allied.pgmex.pgmexec('db',dbConn)

INPUT:

regular:

OUTPUT:

user

user returns the user name of the connection.

 userName=com.allied.pgmex.pgmexec('user',dbConn)

INPUT:

regular:

OUTPUT:

pass

pass returns the password of the connection.

 connPass=com.allied.pgmex.pgmexec('pass',dbConn)

INPUT:

regular:

OUTPUT:

host

host returns the server host name of the connection.

 hostName=com.allied.pgmex.pgmexec('host',dbConn)

INPUT:

regular:

OUTPUT:

port

port returns the port of the connection.

 connPort=com.allied.pgmex.pgmexec('port',dbConn)

INPUT:

regular:

OUTPUT:

options

options Returns the command-line options passed in the connection request.

 connOpt=com.allied.pgmex.pgmexec('options',dbConn)

INPUT:

regular:

OUTPUT:

status

status returns the status of the connection.

 connStatus=com.allied.pgmex.pgmexec('status',dbConn)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

The status can be one of a number of values. However, only two of these are seen outside of an asynchronous connection procedure: CONNECTION_OK (0) and CONNECTION_BAD (1) . A good connection to the database has the status CONNECTION_OK . A failed connection attempt is signaled by status CONNECTION_BAD . Ordinarily, an OK status will remain so until finish command, but a communications failure might result in the status changing to CONNECTION_BAD prematurely. In that case the application could try to recover by calling reset .

errorMessage

errorMessage returns the error message most recently generated by an operation on the connection.

 errMsg=com.allied.pgmex.pgmexec('errorMessage',dbConn)

INPUT:

regular:

OUTPUT:

Most failing PgMex commands throw exceptions. This command is left for backward compatibility.

Working With Parameters

paramCreate

paramCreate creates a new PGparam object for storing command parameters.

pgParam=com.allied.pgmex.pgmexec('paramCreate',dbConn)

INPUT:

regular:

OUTPUT:

paramCount

paramCount returns the number of parameters in a PGparam object.

nParams=com.allied.pgmex.pgmexec('paramCount',pgParam)

INPUT:

regular:

OUTPUT:

paramReset

paramReset clears out any previously put parameters.

com.allied.pgmex.pgmexec('paramReset',pgParam)

INPUT:

regular:

DESCRIPTION:

This function only resets the parameter counter, but does not free any memory. It is useful for reusing the PGparam object. You must still call paramclear in the end.

paramClear

paramclear releases all resources being used by a PGparam object.

pgmexec('paramClear',pgParam)

INPUT:

regular:

putf

putf packs a set of parameters in a PGparam structure for use with a parameterized query.

Put a date, a string, a double vector and a double matrix:

pgmexec('putf',pgParam ,'%date %varchar %float8[]@ %float8[]',...
    datenum('2015-03-26'),'description',[1;2;3;4],[0.1, 0.2; 0.3, 0.4]);

Put an integer matrix with one NULL cell, a NULL value of a boolean array type (null::bool[]) and a NULL value of a varchar type (null::varchar):

SArray=struct('valueMat',[1, 2; 0, 4],'isNullMat',logical([0, 0; 1 0]));
SNull=struct('valueMat',[],'isValueNull',true);
pgmexec('putf',pgParam ,'%int4[] %bool[] %varchar',SArray,SNull,SNull);

Put a string array, a serialized Matlab object (bytea), and an array of serialized Matlab objects (bytea[]):

pgmexec('putf',pgParam ,'%text[] %serbytea %serbytea[]',...
    {'foo','bar';'baz','qux'},struct('arr',[1 2 3]),...
    {[10 20 30],'abcd',@sin});
%
pgmexec('paramClear',pgParam );

when extracted via 'getf’ command with 'serbytea’ field specification, struct('arr’,[1 2 3]) is automatically de-serialized into Matlab structure the same goes for cell elements provided as values for ’%serbytea[]’ field specification

INPUT:

regular:

OUTPUT:

none.

DESCRIPTION

SFieldVal1 ,…, SFieldValN inputs are expected to be formed according to the following rules

Command Execution

exec

exec submits a command to the server and waits for the result.

pgResult=com.allied.pgmex.pgmexec('exec',dbConn,command)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

paramExec

paramExec submits a parameterized command to the server and waits for the result.

pgResult=com.allied.pgmex.pgmexec('paramExec',dbConn,pgParam,commandStr)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

import com.allied.pgmex.pgmexec;
pgParam=pgmexec('paramCreate',dbConn);
pgmexec('putf',pgParam,'%int4 %name',10,'foo');
res=pgmexec('paramExec',dbConn,pgParam,...
    'select * from my_table where ind > $1 and code = $2');
pgmexec('paramClear',pgParam);
% do something with result...
pgmexec('clear',res);

batchParamExec

batchParamExec creates a prepared statement for a given command and executes this statement within batch mode on the server for combinations of parameters values.

Example 1: Insert 100000 tuples, each with an integer, a boolean, a string and an array 1x2 of dates

import com.allied.pgmex.pgmexec;
SData=struct();
SData.mytupleno=transpose(int32(1:100000));
SData.myticker=strcat('foo',cellfun(@num2str,num2cell(transpose(1:100000)),...
    'UniformOutput',false);
startDateVec=datenum('1-Jan-2000')+transpose(0:99999);
SData.mydate_span=[startDateVec startDateVec+30];
SData.ismytuple=randi([0 1],100000,1); % double, but convertible to bool
pgmexec('batchParamExec',dbConn,'insert into my_table1 values ($1,$2,$3,$4)',...
    '%int4 %name %date[] %bool',SData);

Example 2: Insert 100000 tuples, each with a column array of strings, a serialized function_handle and a double array, prefix for prepared statement is defined

SData=struct();
SData.mystr_arr=repmat({{'a','b','c'};{'d'};{'e','f'};{}},25000,1);
SData.myfunc_list=repmat({@sin;@cos},50000,1);
SData.mymeas_mat=repmat({[1 2];[];[1 3;2 4];0.5;[NaN;Inf]},20000,1);
% insert mystr_arr as column array due to '@' postfix
pgmexec('batchParamExec',dbConn,'insert into my_table2 values ($1,$2,$3)',...
    '%varchar[]@ %serbytea %float8[]',SData,[],[],'my_bpe_prefix');

Example 3: Insert 100000 tuples, each with an integer and a string, some elements of values are NULL

SData=struct();
SData.myind=randi([1 10],100000,1); % convertible to int4
tickerCVec={'aaa';'bb';'cccc'};
SData.myticker=tickerCVec(randi([1 3],100000,1));
SIsNull=struct();
SIsNull.myind=repmat([true;false;false;true],25000,1);
SIsNull.myticker=logical(randi([0 1],100000,1));
pgmexec('batchParamExec',dbConn,'insert into my_table3 values ($1,$2)',...
    '%int4 %name',SData,SIsNull);

Example 4: Insert 100000 tuples, each with an integer, a string of length 3, a numeric matrix of arbitrary size and a numeric array 1x2x2, some values are NULL as a whole

SData=struct();
SData.mytupleno=int64(transpose(1:100000));
currMat=['USD';'EUR';'RUB'];
SData.mycurr=currMat(randi([1 3],100000,1),:);
SData.mymeas_mat=repmat({[1 2];[];[1 3;2 4];0.5;[NaN;Inf]},20000,1);
numMat=cat(1,reshape([1 NaN 0.5 -1],1,2,2),reshape([-Inf 0.25 3 Inf],1,2,2),reshape([NaN 0 3 2.5],1,2,2));
SData.mynum_mat=numMat(randi([1 3],100000,1),:,:);
SIsValueNull=struct();
SIsValueNull.mytupleno=false(100000,1);
SIsValueNull.mycurr=repmat([true;false;true;true;false],20000,1);
SIsValueNull.mymeas_mat=logical(randi([0 1],100000,1));
SIsValueNull.mynum_mat=repmat([true;false],50000,1);
pgmexec('batchParamExec',dbConn,'insert into my_table4 values ($1,$2,$3,$4)',...
    '%int8 %varchar %float4[] %float8[]',SData,[],SIsValueNull);

INPUT:

regular:

optional:

OUTPUT:

none.

DESCRIPTION

WHAT DOES THIS COMMAND DO AND HOW

In essence, batchParamExec does the same as several sequential calls of putf and paramExec do (but without creation of pgParam through paramCreate ). The differences are that batchParamExec

This may be useful for such commands as INSERT, UPDATE or DELETE, or if some stored procedure not returning results are executed on the server for some sufficiently large number of parameters values combinations.

GENERAL REMARKS

RULES FOR DATA AND INFO ON NULLS

Example 5: Prepare data for tuples, each with a char and a string of length 3

callPutVec=['C';'P'];
SData.mycall_put=callPutVec(randi([1 2],100000,1)); % use %bpchar in fieldSpecStr
currMat=['USD';'EUR';'RUB'];
SData.mycurr=currMat(randi([1 3],100000,1),:); % use %varchar in fieldSpecStr

Example 6: Prepare data for tuples, each with a numeric array 1x2x2

measMat=cat(1,reshape([1 NaN 0.5 -1],1,2,2),...
    reshape([-Inf 0.25 3 Inf],1,2,2),...
    reshape([NaN 0 3 2.5],1,2,2));
SData.mymeas_mat=measMat(...
    randi([1 3],100000,1),:,:); % use %float4[] or %float8[] in fieldSpecStr

Example 7: Prepare data and info on NULLs for tuples, each with a string array and an array of numeric matrices

SData=struct();
SData.myticker_vec=repmat(...
    {{'aaa','aa'};{'bbbb','bbbbb',''}},...
    50000,1); % use %varchar[] in fieldSpecStr
SData.mymeas_mat=repmat(...
    {[1 2];[1 3;2 4];0.5;[NaN;Inf]},...
    25000,1); % use %float4[] or %float8[] in fieldSpecStr
SIsNull=struct();
SIsNull.myticker_vec=repmat({[false true];false;[false true false]},50000,1);
SIsNull.mymeas_mat=repmat({[true false];false(2,2);true;[false;true]},25000,1);

Example 8: Prepare data and info on NULLs for tuples, each with a numeric array 1x2x2

SData=struct();
measMat=cat(1,reshape([1 NaN 0.5 -1],1,2,2),...
    reshape([-Inf 0.25 3 Inf],1,2,2),...
    reshape([NaN 0 3 2.5],1,2,2));
SData.mymeas_mat=measMat(...
    randi([1 3],100000,1),:,:); % use %float4[] or %float8[] in fieldSpecStr
SIsNull=struct();
SIsNull.mymeas_mat=logical(randi([0 1],100000,2,2));

pqExec

pqExec submits a command to the server and waits for the result ( libpq version).

pgResult=com.allied.pgmex.pgmexec('pqExec',dbConn,command)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

resultStatus

resultStatus returns the result status of the command.

execStatus=com.allied.pgmex.pgmexec('resultStatus',pgResult)

INPUT:

regular:

OUTPUT:

Code value Code name Code description
0 EMPTY_QUERY empty query string was executed
1 COMMAND_OK a query command that doesn’t return anything was executed properly by the backend
2 TUPLES_OK a query command that returns tuples was executed properly by the backend, PGresult contains the result tuples
3 COPY_OUT Copy Out data transfer in progress
4 COPY_IN Copy In data transfer in progress
5 BAD_RESPONSE an unexpected response was recv’d from the backend
6 NONFATAL_ERROR notice or warning message
7 FATAL_ERROR query failed
8 COPY_BOTH Copy In/Out data transfer in progress
9 SINGLE_TUPLE single tuple from larger resultset

resultErrorMessage

resultErrorMessage returns the error message associated with the command or an empty string if there was no error.

errMsg=pgmexec('resultErrorMessage',pgResult)

INPUT:

regular:

OUTPUT:

Normally, execution commands such as exec throw an exception on errors. This command is left for backward compatibility.

clear

clear frees the storage associated with a PGresult .

com.allied.pgmex.pgmexec('clear',pgResult)

INPUT:

regular:

Every command result should be freed via clear when it is no longer needed.

Retrieving Query Result

nTuples

nTuples returns the number of rows (tuples) in the query result.

nTuples=com.allied.pgmex.pgmexec('nTuples',pgResult)

INPUT:

regular:

OUTPUT:

nFields

nFields returns the number of columns (fields) in each row of the query result.

nFields=com.allied.pgmex.pgmexec('nFields',pgResult)

INPUT:

regular:

OUTPUT:

fName

fName returns the column name associated with the given column number.

fName=com.allied.pgmex.pgmexec('fName',pgResult,colInd)

INPUT:

regular:

OUTPUT:

fNumber

fNumber returns the column number associated with the given column name.

fnum=com.allied.pgmex.pgmexec('fNumber',pgResult,colName)

INPUT:

regular:

OUTPUT:

pgResult=com.allied.pgmex.pgmexec('exec',dbConn,'SELECT 1 AS FOO, 2 AS "BAR"');
%
name=com.allied.pgmex.pgmexec('fName',pgResult,0)             % foo
name=com.allied.pgmex.pgmexec('fName',pgResult,1)             % BAR
ind=com.allied.pgmex.pgmexec('fNumber',pgResult,'FOO')        % 0
ind=com.allied.pgmex.pgmexec('fNumber',pgResult,'foo')        % 0
ind=com.allied.pgmex.pgmexec('fNumber',pgResult,'BAR')        % -1
ind=com.allied.pgmex.pgmexec('fNumber',pgResult,'"BAR"')      % 1

fSize

fSize returns the size in bytes of the column associated with the given column number.

fSize=com.allied.pgmex.pgmexec('fSize',pgResult,colInd)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

This function returns the size of the server’s internal representation of the data type. Accordingly, it is not really very useful to end-users.

binaryTuples

binaryTuples returns true if the PGresult contains binary data and false if it contains text data.

isBinary=com.allied.pgmex.pgmexec('binaryTuples',pgResult)

INPUT:

regular:

OUTPUT:

getValue

getValue returns a single field value of one row of a PGresult .

valueStr=com.allied.pgmex.pgmexec('getValue',pgResult,rowInd,colInd)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

getIsNull

getIsNull tests a field for a NULL value.

isNull=com.allied.pgmex.pgmexec('getIsNull',pgResult,rowInd,colInd)

INPUT:

regular:

OUTPUT:

getLength

getLength returns the actual length of a field value in bytes.

length=com.allied.pgmex.pgmexec('getLength',pgResult,rowInd,colInd)

INPUT:

regular:

OUTPUT:

DESCRIPTION:

This function returns the length of the data pointed by PQgetValue (but not necessarily by the MEX functions getValue or getf ). It is not likely to be useful to end users and is left for backward-compatibility.

getf

getf gets one or more field values from PGresult using a scanf -style interface.

Select all data (i.e. select *) from a table with 2 tuples and the following columns:

( event_id bigint, t_date date, metric_name character(1), metric_value double precision[])

 import com.allied.pgmex.pgmexec;
 [SId,SDate,SName,SValue]=pgmexec('getf',pgResult,'%int8 #date %varchar %float8[]',...
     0,'t_date',1,2);
% SId.valueVec={int64(5645334);int64(645647)}
% SId.isNullVec=[false;false]
% SId.isValueNullVec=[false;false]
%
% SDate = struct with fields:
%          valueVec: [2x1 double]
%         isNullVec: [2x1 logical]
%    isValueNullVec: [2x1 logical]
%
dateVec=SDate.valueVec
%
% dateVec =[736666;736667]
%
% SName = struct with fields:
%           valueVec: {2x1 cell}
%          isNullVec: [2x1 logical]
%     isValueNullVec: [2x1 logical]
%
nameCVec=SName.valueVec
% nameCVec ={'Experiment #1','Experiment #2'}
%
% empty value for the second extracted metric:
% SValue.valueVec={[0 2.4;-2 Inf;0 NaN];[]}
% some elements in the value matrix for the first metric are null:
% SValue.isNullVec={[true false;false false;true false];logical.empty(0,0)}
% the value extracted for the second metrics is empty because it is NULL:
% SValue.isValueNullVec=[false;true]

Note that in this example in the first two output structures the 'valueVec’ field is a column vector (int64 and double respectively), while in the last two structures 'valueVec’ is a cell array. 'isNullVec’ is a logical column vector in the first three structures and a cell array of logical arrays in the last structure.

INPUT:

regular:

properties:

OUTPUT:

DESCRIPTION:

The structures SFieldValue1,…,SFieldValueN have the following fields:

If isUniformOutput is false, then in any case both valueVec and isNullVec are cell[nTuples,1], such that elements of valueVec contain values of corresponding fields while cells of isNullVec are logical matrices determinining whether these values are NULL or not. If isUniformOutput is true, then the format described above for both valueVec and isNullVec is valid only for fields with non-scalar values, for fields with scalar values valueVec is plain (not cell) array of size [nTuples,1] of these values while isNullVec is logical[nTuples,1]. Thus, if isUniformOutput is true, then values of valueVec and isNullVec obtained in general case are concatenated in simple column vectors. isValueNullVec indicates, for each tuple, whether the entire value, be it a scalar or an array, is NULL.

Retrieving Other Result Info

cmdStatus

cmdStatus returns the command status tag from the SQL command that generated the PGresult .

statusStr=com.allied.pgmex.pgmexec('cmdStatus',pgResult)

INPUT:

regular:

OUTPUT:

cmdTuples

cmdTuples returns the number of rows affected by the SQL command.

tuplesStr=com.allied.pgmex.pgmexec('cmdTuples',pgResult)

INPUT:

regular:

OUTPUT:

Copyright 2016-2020 Allied Testing Ltd.