How to define an IIO device in kernel in order to call the probe of the corresponding driver? [duplicate] - linux-device-driver

On my x86_64 board, there is i2c-bus coming out of a MFD device. There are devices on to this i2c-bus. I am able to detect these devices using i2cdetect program.
# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- 4c -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
I need the kernel to detect these devices automatically, So, I tried writing i2c_board_info as in given below code, But still, the kernel is not able to detect these devices automatically.
#include <linux/init.h>
#include <linux/i2c.h>
#define BUS_NUMBER 0
static struct __init i2c_board_info tst_i2c0_board_info[] = {
{
I2C_BOARD_INFO("ltc2990", 0x4c),
},
{
I2C_BOARD_INFO("24c128", 0x57),
},
};
static int tst_i2c_board_setup(void)
{
int ret=-1;
ret = i2c_register_board_info(BUS_NUMBER, tst_i2c0_board_info, ARRAY_SIZE(tst_i2c0_board_info));
return ret;
}
device_initcall(tst_i2c_board_setup);
Any suggestions on how can I solve this ?

Since you have an ACPI-enabled platform the best approach is to provide the ASL excerpts for given devices.
Because of Intel Galileo platform for IoT the Atmel 24 series EEPROM has got its own ACPI ID and an excerpt will be simple:
DefinitionBlock ("at24.aml", "SSDT", 5, "", "AT24", 1)
{
External (_SB_.PCI0.I2C2, DeviceObj)
Scope (\_SB.PCI0.I2C2)
{
Device (EEP0) {
Name (_HID, "INT3499")
Name (_DDN, "Atmel AT24 compatible EEPROM")
Name (_CRS, ResourceTemplate () {
I2cSerialBusV2 (
0x0057, // I2C Slave Address
ControllerInitiated,
400000, // Bus speed
AddressingMode7Bit,
"\\_SB.PCI0.I2C2", // Link to ACPI I2C host controller
0
)
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"size", 1024},
Package () {"pagesize", 32},
}
})
}
}
}
Note, the size property is being added in a pending patch series (patches add eeprom "size" property and add support to fetch eeprom device property "size").
Note, the address width is 8-bit as hard coded for now. In case you need to have 16-bit you need to create a similar patches as mentioned above.
For LTC2990 power monitor you need the following excerpt:
DefinitionBlock ("ltc2990.aml", "SSDT", 5, "", "PMON", 1)
{
External (\_SB_.PCI0.I2C2, DeviceObj)
Scope (\_SB.PCI0.I2C2)
{
Device (PMON)
{
Name (_HID, "PRP0001")
Name (_DDN, "Linear Technology LTC2990 power monitor")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x4c, // Bus address
ControllerInitiated, // Don't care
400000, // Fast mode (400 kHz)
AddressingMode7Bit, // 7-bit addressing
"\\_SB.PCI0.I2C2", // I2C host controller
0 // Must be 0
)
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "lltc,ltc2990"},
}
})
}
}
}
Note, unfortunately there is no compatible string in the driver, so, one needs to add it like it's done here.
In the examples above \\_SB.PCI0.I2C2 is an absolute path to the I2C host controller.
How to get those files applied:
first of all, create a folder
mkdir -p kernel/firmware/acpi
save files under names mentioned in the DefinitionBlock() macro in that folder
create the uncompressed cpio archive and concatenate the original initrd on top:
find kernel | cpio -H newc --create > /boot/instrumented_initrd
cat /boot/initrd >> /boot/instrumented_initrd
More details are available in SSDT Overlays.
The other examples and description of the idea behind can be found on meta-acpi GitHub page, some materials from which are copied here.

After going through Documentation/i2c/instantiating-devices, I understand there are several methods to do the same(e.g. as 0andriy suggested usng acpi table etc), I used "i2c_new_probed_device" method. Below is the used code :
#include <linux/init.h>
#include <linux/i2c.h>
#define BUS_NUMBER 0
#define NUM_DEVICE 2
static const unsigned short normal_i2c[][2] = {
{0x4c, I2C_CLIENT_END},
{0x57, I2C_CLIENT_END},
};
static struct i2c_board_info tst_i2c0_board_info[2] = {
{I2C_BOARD_INFO("ltc2990", 0x4c), },
{I2C_BOARD_INFO("24c128", 0x57), },
};
static int tst_i2c_board_setup(void)
{
int i = 0;
struct i2c_adapter *i2c_adap;
i2c_adap = i2c_get_adapter(BUS_NUMBER);
for(i = 0; i < NUM_DEVICE; i++)
i2c_new_probed_device(i2c_adap, &tst_i2c0_board_info[i],
normal_i2c[i], NULL);
i2c_put_adapter(i2c_adap);
return 0;
}
late_initcall(tst_i2c_board_setup);

Related

WHENEVER SQLERROR of postgresql causes INTO assignment to fail

This is a piece of ecpg code. When using fetch to traverse the data, because of the use of WHENEVER SQLERROR DO sqlerr(), if an error occurs, it will be judged by the sqlerr method that it is a 22002 error, and the error will be ignored and the traversal will continue
int main(int argc, char *argv[]) {
....
EXEC SQL DECLARE mt_cur CURSOR WITH HOLD FOR
SELECT
C1, C2, C3
FROM MYTABLE,
ORDER BY C1;
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL CLOSE mt_cur;
EXEC SQL WHENEVER SQLERROR DO sqlerr();
EXEC SQL OPEN mt_cur;
EXEC SQL WHENEVER NOT FOUND DO break;
while (1) {
EXEC SQL FETCH mt_cur INTO :v1, :v2, :v3;
if (v3 > 5 ) {
continue;
}
printf("%d%d\n", v1, v3);
}
EXEC SQL CLOSE mt_cur;
....
return (0);
}
void sqlerr() {
if (strncmp(sqlca.sqlstate, "22002", 5) == 0) {
return;
}
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK WORK;
exit(1);
}
If the data in the table is like this
C1 C2 C3
1 0 2
2 (NULL) 8
3 (NULL) 9
The correct running result should be to print only one 12, but now it prints out 12, 22, 32
After analyzing the program, I think that when traversing the second row of data, the C2 column is NULL, which leads to entering the sqlerr method. After returning in sqlerr, INTO will not be executed to assign a value to v3, and it will enter the next traversal. At this time, the value of v3 is 2 assigned during the first traversal
Is my idea correct? If so, is there a way for postgresql to avoid this situation, I want the value of C3 to be INTO to v3 normally when C2 is NULL

I/O error in Python SMBus after executing the code including BCM2835 libs

I tried coding a driver between Rpi zero 2 and MLX60640. The script is based on IIC and bcm2835 lib. However, after I have closed the I/O bus at the end of my C code, the tool of i2c-detect and SMBus lib in python3 will return errors.
For the first one, the response time to each address in the bus is as slow as 1 second (approx.) and the address, 0x33, is not detected in the stdout, in python, the SMBus will return an I/O error after my code is executed. The problem will be handled after the system is rebooted.
What's more, the issue is not only detected in this sensor, all the other devices will behave the same when I use the BCM2835 lib.
The description for the sensor MLX90640 is here. https://www.melexis.com/-/media/files/documents/datasheets/mlx90640-datasheet-melexis.pdf
below is my code:
#include <bcm2835.h>
#include <stdint.h>
#include <stdio.h>
#define M9Addr 0x33
#define BADURATE 1000
void MLX_init(uint8_t address, int badurate)
{
if(!bcm2835_init())
{
printf("error\n");
return;
}
bcm2835_i2c_end();
bcm2835_i2c_begin();
bcm2835_i2c_setSlaveAddress(M9Addr);
bcm2835_i2c_set_baudrate(badurate);
bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_150);
return;
}
void MLX_deStruct(void)
{
bcm2835_i2c_end();
bcm2835_close();
return;
}
int main(int argc, char* argv[])
{
MLX_init(M9Addr,BADURATE);
MLX_deStruct();
return(0);
}
i2ctools returning:
pi#raspzero2old:~/ther $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- ^C

ASN1 module compiled by asn1c fails to decode?

I'm trying to parse RSA (private) keys using asn1c. I based the asn1 module on https://www.rfc-editor.org/rfc/rfc3447 and it looks as following (i tried to only use the private and public key part):
-- ===================
-- Main structures
-- ===================
RSAPrivateKey DEFINITIONS ::=
BEGIN
--
-- Representation of RSA private key with information for the CRT
-- algorithm.
--
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
Version ::= INTEGER { two-prime(0), multi(1) }
(CONSTRAINED BY {
-- version must be multi if otherPrimeInfos present --
})
OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
OtherPrimeInfo ::= SEQUENCE {
prime INTEGER, -- ri
exponent INTEGER, -- di
coefficient INTEGER -- ti
}
END -- PKCS1Definitions
However when i compile the module and try to parse .der private key using the following, it ends with RC_FAIL.
RSAPrivateKey_t *rsa_p_key;
rsa_p_key= (RSAPrivateKey_t*)calloc(1, sizeof *rsa_p_key);
asn_dec_rval_t rval = ber_decode(
0,
&asn_DEF_RSAPrivateKey,
(void**)&rsa_p_key,
buffer, // buffer containing key (unsigned char*)
buffer_len); // buffer length (amount of read bytes)
I've been trying to find the error in asn1 module, but with no luck. Using openssl to print out the .der file, it seems to match the RSAPrivateKey. I also tested for erronous file reading, but buffer matches and binary read mode is used.
You need to compile with -fwide-types flag.
-fwide-types Use the wide integer types (INTEGER_t, REAL_t) instead of ma-chine’s native data types (long, double).
The problem is that most of the INTEGER fields of RSAPrivateKey contain really big numbers that not fit in long type that is being used by default.
Without -fwide-types
/* RSAPrivateKey */
typedef struct RSAPrivateKey {
Version_t version;
long modulus;
long publicExponent;
long privateExponent;
With -fwide-types
/* RSAPrivateKey */
typedef struct RSAPrivateKey {
Version_t version;
INTEGER_t modulus;
INTEGER_t publicExponent;
INTEGER_t privateExponent;
$ asn1c -fwide-types rfc3447.asn1
$ make -f converter-example.mk
$ ./converter-example -p RSAPrivateKey -iber ./temp/key.der
<RSAPrivateKey>
<version>0</version>
<modulus>00:C1:3D:F5:BD:51:55:B8:94:45:B9:93:53:46:81:58:77:F0:3A:30:75:30:40:F5:84:C2:6C:11:00:6A:00:CC:15:5D:FD:6F:04:1F:3F:92:39:84:AF:8D:DC:3C:58:84:2A:54:9B:AC:E7:77:55:FF:C5:95:94:F6:D7:16:C3:AA:B7:31:0B:BB:72:1A:A4:45:50:D3:D7:3A:98:C6:A0:8E:1F:66:AE:5F:40:94:46:26:64:22:07:F5:84:D8:AD:BD:C6:D1:00:4B:50:FB:66:BF:D1:05:61:84:3B:0D:6D:1E:9C:1F:CB:0C:35:FC:A5:FA:AF:8A:DD:14:0A:3E:1F:8F:E2:40:C0:4F:A2:3D:90:97:10:7F:A1:92:74:C9:97:6A:AD:E9:66:C8:0A:DE:91:88:8B:CB:DD:09:7D:35:CD:78:00:88:0D:A6:CE:1E:71:8C:7D:96:68:74:9E:F4:7E:CA:1A:82:AF:5E:42:A3:6A:60:47:98:00:CA:2A:59:D4:86:CA:AF:B5:CA:C2:38:1A:04:3E:33:86:81:17:78:27:BA:E3:17:D1:52:5A:DF:B5:31:9C:D4:4B:5C:06:EC:93:80:06:86:FB:33:55:68:30:72:91:36:B4:C7:6B:EB:3A:A6:40:0F:C3:78:ED:1A:22:0E:F9:77:44:65:91:E5:C5:B1:53</modulus>
<publicExponent>65537</publicExponent>
<privateExponent>00:9E:85:B7:8B:80:A7:73:6D:9E:ED:27:60:4F:1C:58:78:BB:86:E0:AD:A1:D2:08:16:CA:6F:60:5B:18:9A:62:D0:BC:73:E4:98:5B:12:09:60:49:EA:C1:D3:03:66:11:B5:B0:06:AD:06:8C:AC:ED:CF:26:70:37:36:27:24:88:6D:13:3C:EE:9E:22:20:D4:04:04:64:31:5B:96:C5:AB:11:33:68:A4:17:14:0B:9F:FE:D0:B3:FA:C2:EA:05:4D:03:45:FC:99:CC:6B:0F:D5:17:20:F4:E8:46:91:33:0C:C3:42:89:8D:10:D4:9B:4C:54:A8:F3:C7:36:C7:D3:98:71:B3:3E:FC:37:CB:E4:7D:68:11:BF:42:6B:C4:1E:F9:0C:B8:AD:10:F1:58:C8:66:11:CF:84:09:B0:B2:BE:1E:50:3C:80:F1:09:D4:C7:FD:35:3B:EE:AB:AB:14:1F:D1:78:56:EC:98:AE:37:C6:7E:DF:87:EF:76:A6:C4:E5:21:84:73:12:41:F7:C7:17:69:85:B0:C1:FA:9F:E5:11:A0:29:F5:95:22:64:BB:5D:4E:6E:52:A6:BA:E6:50:23:8C:D7:BB:69:C4:D1:36:B3:62:37:0E:C5:76:B0:D3:14:D7:7C:B3:4A:4F:58:59:F0:16:F1:19:42:12:6B:A3:D6:73:71</privateExponent>
<prime1>00:E7:38:46:89:D6:43:E5:A2:80:F7:EB:03:8B:15:B0:24:CE:9E:0F:4F:4D:1C:C5:7F:15:9B:12:05:D5:4C:20:C8:D2:9C:7C:30:3F:99:84:3A:6E:4B:BA:A0:BF:34:40:C3:30:80:D1:AE:6B:04:C6:DB:E0:FA:5F:65:14:96:0B:3B:9A:75:8E:84:C2:F5:96:98:09:09:87:2F:62:19:87:AB:BB:C7:87:67:67:07:61:5B:8B:CC:B2:19:52:74:1C:91:F7:12:F0:E5:9B:B3:3C:81:2E:F4:2A:E4:AC:56:6D:38:95:DB:18:5E:7B:4F:96:B1:E5:80:41:C2:28:AC:2A:E7</prime1>
<prime2>00:D5:F3:BA:B4:3C:3B:B0:02:0C:E9:BA:21:CC:03:23:26:F5:0B:2B:27:B0:74:C6:E2:F8:FD:3F:CB:1F:CA:1A:B9:12:4C:B6:7E:56:D4:AB:A8:F2:8D:81:54:63:0C:0E:16:79:54:0B:7C:13:7F:E6:66:12:BD:A0:62:F3:D6:8A:AC:B5:2A:58:70:58:8C:16:94:95:97:2D:9C:2A:A8:30:3F:35:43:57:D7:79:3D:9B:EF:56:95:A0:81:24:DC:67:C5:DA:66:F0:7E:02:94:59:4C:1B:EB:AB:67:0E:B6:C3:BD:92:0B:7C:B4:8E:44:AE:32:1A:42:A1:C7:93:6A:44:B5</prime2>
<exponent1>00:82:E3:65:72:E3:9A:FD:E4:36:D3:A0:F3:19:89:C6:73:9F:8E:F4:25:B5:06:43:7A:84:55:8B:27:48:2E:57:24:B7:AC:A3:D4:80:3C:3C:11:03:9C:D4:E1:E8:3B:01:2A:3D:4B:BE:E6:D8:68:14:D6:25:8E:35:F0:37:6E:14:9F:C1:F9:28:1B:59:6D:C2:B8:FF:EC:A7:DD:17:D0:51:EF:D2:55:C9:FD:AB:E2:0E:A7:CF:04:AA:11:11:8E:EF:19:65:DF:10:05:3A:55:85:3B:AF:C3:C2:80:3E:5A:92:6B:84:D1:49:03:3B:14:BB:BE:AA:A7:27:12:6D:09:C1:23</exponent1>
<exponent2>6E:22:70:D1:A6:CF:F2:E2:9B:53:15:85:A0:47:5D:29:08:AB:1F:23:E7:29:B5:D7:D0:E4:4C:9A:7B:5A:C6:36:CE:BC:BE:94:7A:8E:2F:6F:60:AC:87:0E:B1:8D:DB:12:A6:92:24:F7:51:F2:5C:DF:DE:75:CE:C2:21:53:27:3F:90:62:A3:F3:F1:20:EB:DE:C0:C2:79:B0:12:25:51:F0:B7:B2:5A:DD:88:83:B6:69:95:E0:A0:26:DA:9A:BA:B0:96:A4:B6:D7:A6:EC:46:AB:6F:13:F9:BF:AB:4B:59:A7:94:2E:65:9B:6C:40:DE:8A:DC:09:C0:CD:C3:8C:C8:A1</exponent2>
<coefficient>43:9A:41:22:B1:F4:15:A9:C7:95:FD:F7:7E:55:BC:24:16:5F:E2:9D:B0:D5:74:54:1B:F6:C9:76:C4:6A:4E:5E:6C:AE:71:E1:9A:DE:F1:26:47:B4:41:45:BD:0A:2E:E4:02:DE:AD:28:21:2D:50:59:99:DA:26:E0:90:1A:84:2B:22:46:48:CC:DB:1F:7E:9B:9B:F5:02:D8:24:6F:7E:F3:D9:30:91:1F:83:22:9A:94:C7:F4:29:B2:93:68:CB:57:BC:C5:60:96:0E:42:42:55:D2:3A:71:B5:31:78:D3:D1:2A:74:03:C2:45:A2:9A:A2:89:6F:62:63:C6:42:7B:2D</coefficient>
</RSAPrivateKey>

Query to check whether table is journaled in DB2

I am new to db2.
Is there a query to check whether a table is journaled in DB2 or not. if it is journaled what is the name of the journal.
I found this query: Find all journals in library MJATST.
SELECT * FROM TABLE (QSYS2.OBJECT_STATISTICS('MJATST ','JRN') ) AS X
but i couldn't find something similar to tables in schema.
I'm not aware of any and a quick search of the likely catalogs didn't turn up a way.
http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/db2/rbafzcatalog.htm
The journal information is available in the Retrieve Object Description (QUSROBJD) API
http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/apis/qusrobjd.htm
You could wrap that API in a UDF.
The following is an example of a CLLE source that can be used at least as far back as v5r3 [no advantage is taken of newer CL support to make the code more succinct] to create a bound ILE CL *PGM object that is invoked as a scalar function [as was previously] defined to the SQL by the CREATE FUNCTION shown in the block comments preceding the CL source; a very simple test-suite verified the functionality:
/* create function jrnOfDBF */
/* ( table_name varchar(128) */
/* , table_libr varchar( 10) */
/* ) returns char(20) */
/* language PLI -- a lie to allow VARCHAR inputs */
/* specific jrnOfDBF */
/* not deterministic */
/* no sql returns null on null input */
/* disallow parallel not fenced no external action */
/* parameter style SQL */
/* external name jrnOfDBF */
/* */
/* CRTBNDCL PGM(JRNOFDBF) SRCMBR(..following_source..) */
/* */
pgm (&tblnam &tbllib +
&rtnval &rtnind &sqlste &udfnam &specnm &diagmg)
dcl &tblnam *char 130
dcl &tbllib *char 12
dcl &rtnval *char 20
dcl &rtnind *int 2
dcl &sqlste *char 5
dcl &udfnam *char 141
dcl &specnm *char 130
dcl &diagmg *char 72
/* Pgm Vars */
dcl &lngnam *char 128
dcl &lnglib *char 10
dcl &dbflib *char 10
dcl &dbfobj *char 10
dcl &jrnsts *char 1
dcl &jrnlib *char 10
dcl &jrnobj *char 10
dcl &strlen *int 4
dcl &qualnm *char 20
monmsg cpf0000 exec(goto badthing)
main:
chgvar &strlen (%bin(&tbllib 1 2))
chgvar &lnglib (%sst(&tbllib 3 &strlen))
chgvar &strlen (%bin(&tblnam 1 2))
chgvar &lngnam (%sst(&tblnam 3 &strlen))
call qdbrtvsn (&qualnm &lngnam &strlen &lnglib x'0000000000000000')
/* 1 Qualified object name Output Char( 20) */
/* 2 Long object name Input Char(128) */
/* 3 Length of long object name Input Binary(4) */
/* 4 Library name Input Char( 10) */
/* 5 Error code I/O Char( * ) */
chgvar &dbflib (%sst(&qualnm 11 10))
chgvar &dbfobj (%sst(&qualnm 01 10))
rtvobjd &dbflib/&dbfobj *file aspdev(*) +
jrnsts(&jrnsts) jrn(&jrnobj) jrnlib(&jrnlib)
if (&jrnsts *eq '1') then(do)
chgvar &rtnval (&jrnobj *cat &jrnlib) /* qualified name of jrn */
enddo
/* else &rtnval is already blanks */
chgvar &rtnind 0
mainend:
return
badthing:
chgvar &rtnind -1
chgvar &sqlste 'JRN99'
chgvar &diagmg 'Unable to retrieve Obj Info; see joblog'
sndpgmmsg *n cpf9898 qcpfmsg &diagmg tomsgq(*topgmq) topgmq(*prv) +
msgtype(*diag)
goto mainend
endpgm
An example invocation of the function:
select jrnOfDBF('SYSROUTINES', 'QSYS2') from qsys2.qsqptabl
What the interactive Start SQL (STRSQL) display report would show:
....+....1....+....2
JRNOFDBF
QSQJRN QSYS2
******** End of data ********
Note: The value of blanks being returned is indicative of either currently not journaled or never journaled, whereas any non-blank value should be the qualified-name of the journal in the standard form of: '10bytObjNm10bytLibNm'
I used DSPFD command for the file(table).. It specifics bunch of info about the file(table)..
MBJRNL -(N/Y) whether table has journal associated with it
if Y then you can get journal info from following column else this column will be null
MBJRNM - Journal Name
MBJRLB - Journal Schema
hope this helps anyone looking for something similar!!

Perl+Postgresql: a function does not return a value if RAISE NOTICE is present

I noticed that when I call a PL/PgSQL or PL/Perl function from a Perl script using DBI, it does not return a value if a RAISE NOTICE or elog(NOTICE) is used in the function. To illustrate:
A simple table:
CREATE TABLE "public"."table1" (
"fld" INTEGER
) WITHOUT OIDS;
A simple function:
CREATE OR REPLACE FUNCTION "public"."function1" () RETURNS integer AS
$body$
DECLARE
myvar INTEGER;
BEGIN
SELECT INTO myvar fld FROM table1 LIMIT 1;
RETURN myvar;
END;
$body$
LANGUAGE 'plpgsql'
A piece of Perl script:
use DBI;
...
my $ref = $dbh->selectcol_arrayref('SELECT function1()');
print $$ref[0];
As it is, it prints the value from the table.
But I get no result if I add RAISE NOTICE as follows:
SELECT INTO myvar fld FROM table1 LIMIT 1;
RAISE NOTICE 'Testing';
RETURN myvar;
Am I missing something or such behavior is by design?
Check the client_min_messages setting in your database server's postgresql.conf file. From the PostgreSQL 8.3 docs:
client_min_messages (string)
Controls which message levels are sent to the client. Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, LOG, NOTICE, WARNING, ERROR, FATAL, and PANIC. Each level includes all the levels that follow it. The later the level, the fewer messages are sent. The default is NOTICE. Note that LOG has a different rank here than in log_min_messages.
I can't reproduce this, using Debian's Perl 5.10, DBI 1.605 and DBD::Pg 2.8.7 against PostgreSQL 8.3.7. I get the notice printed out as expected.
steve#steve#[local] =# create or replace function public.function1() returns integer language 'plpgsql' as $$ declare myvar integer; begin select into myvar fld from table1 limit 1; raise notice 'Testing'; return myvar; end; $$;
CREATE FUNCTION
steve#steve#[local] =#
[1]+ Stopped psql --cluster 8.3/steve
steve#arise:~$ DBI_TRACE=1 perl -MData::Dumper -MDBI -e '$dbh = DBI->connect(qw|dbi:Pg:dbname=steve;port=5433;host=/tmp steve steve|, {RaiseError=>1,PrintError=>0}); print Data::Dumper->new([$dbh->selectcol_arrayref("SELECT function1()")], [qw|result|])->Dump'
DBI 1.605-ithread default trace level set to 0x0/1 (pid 5739) at DBI.pm line 273 via -e line 0
Note: perl is running without the recommended perl -w option
-> DBI->connect(dbi:Pg:dbname=steve;port=5433;host=/tmp, steve, ****, HASH(0x1c9ddf0))
-> DBI->install_driver(Pg) for linux perl=5.010000 pid=5739 ruid=1000 euid=1000
install_driver: DBD::Pg version 2.8.7 loaded from /usr/lib/perl5/DBD/Pg.pm
<- install_driver= DBI::dr=HASH(0x1e06a68)
!! warn: 0 CLEARED by call to connect method
<- connect('dbname=steve;port=5433;host=/tmp', 'steve', ...)= DBI::db=HASH(0x1fd8e08) at DBI.pm line 638
<- STORE('RaiseError', 1)= 1 at DBI.pm line 690
<- STORE('PrintError', 0)= 1 at DBI.pm line 690
<- STORE('AutoCommit', 1)= 1 at DBI.pm line 690
<- STORE('Username', 'steve')= 1 at DBI.pm line 693
<> FETCH('Username')= 'steve' ('Username' from cache) at DBI.pm line 693
<- connected('dbi:Pg:dbname=steve;port=5433;host=/tmp', 'steve', ...)= undef at DBI.pm line 699
<- connect= DBI::db=HASH(0x1fd8e08)
<- STORE('dbi_connect_closure', CODE(0x1da2280))= 1 at DBI.pm line 708
NOTICE: Testing
<- selectcol_arrayref('SELECT function1()')= ( [ '2' ] ) [1 items] at -e line 1
$result = [
'2'
];
I suggest isolating your problem to a small script (like above) and running it with DBI_TRACE set fairly high any seeing what differences you see. Maybe also looking at the release notes for DBD::Pg and seeing if they mention it maybe having been confused by these in the past. With DBI_TRACE=10 I see this:
PQexec
Begin pg_warn (message: NOTICE: Testing
DBIc_WARN: 1 PrintWarn: 1)
NOTICE: Testing
End pg_warn
Begin _sqlstate
So you should be looking for something like that in your own output.