使用ecpg和postgresql,无法解析布尔字段

时间:2015-09-11 19:38:02

标签: postgresql ecpg

我正在尝试从PostgreSQL中检索记录

我使用以下脚本创建数据库,表并用一些记录填充它:

psql << "EOF"
  CREATE DATABASE todo;

\c todo

CREATE TABLE items
(
  id        serial PRIMARY KEY,
  task      VARCHAR(40) NOT NULL,
  complete  boolean
);

INSERT INTO items (id, task, complete) VALUES (1, 'task1', true);
INSERT INTO items (id, task, complete) VALUES (2, 'task2', true);
INSERT INTO items (id, task, complete) VALUES (3, 'task3', true);
INSERT INTO items (id, task, complete) VALUES (4, 'task4', true);
INSERT INTO items (id, task, complete) VALUES (5, 'task5', false);
INSERT INTO items (id, task, complete) VALUES (6, 'task6', false);

EOF

我使用a)结构以及b)个别变量来处理问题。方法a)无法解析布尔字段完整。这是程序:

#include <stdio.h>
#include <stdlib.h>
#include <ecpglib.h>


int
main(void)
{
#if ENABLE_DEBUG
  ECPGdebug(1, stderr);
#endif
  EXEC SQL WHENEVER SQLERROR sqlprint;


EXEC SQL BEGIN DECLARE SECTION;
  /* Use structure as host variable */
  typedef struct {
    int   id;
    char  task[40];
    bool  complete;
  } item_t;
  item_t  item;

  /* Use individual variables as host variables */
  int   id;
  char  task[40];
  bool  complete;

EXEC SQL END DECLARE SECTION;

  memset(&item, 0, sizeof(item_t));

  EXEC SQL CONNECT TO todo;

  /*
   * Use structure as host variable
   */
  EXEC SQL DECLARE cur1 CURSOR FOR
    SELECT id, task, complete
      FROM items;
  EXEC SQL OPEN cur1;

  printf("sizeof(item_t) = %ld\n", sizeof(item));
  printf("   sizeof(item.int)      = %ld\n", sizeof(item.id));
  printf("   sizeof(item.task)     = %ld\n", sizeof(item.task));
  printf("   sizeof(item.complete) = %ld\n", sizeof(item.complete));

  printf("\n"
         "Using structure variable\n"
         "------------------------\n");

  EXEC SQL WHENEVER NOT FOUND DO BREAK;
  while (1)
  {
    EXEC SQL FETCH FROM cur1 INTO :item;

    printf("id=%d, task=%s, complete=%d\n\n",
           item.id, item.task, item.complete);
  }
  EXEC SQL CLOSE cur1;



  /*
   * Use individual variables as host variables
   */
  EXEC SQL DECLARE cur2 CURSOR FOR
    SELECT id, task, complete
      FROM items;
  EXEC SQL OPEN cur2;

  printf("sizeof(int)      = %ld\n", sizeof(id));
  printf("sizeof(task)     = %ld\n", sizeof(task));
  printf("sizeof(complete) = %ld\n", sizeof(complete));

  printf("\n"
         "Using individual variables\n"
         "--------------------------\n");

  EXEC SQL WHENEVER NOT FOUND DO BREAK;
  while (1)
  {
    EXEC SQL FETCH FROM cur2 INTO :id, :task, :complete;

    printf("id=%d, task=%s, complete=%d\n",
            id, task, complete);
  }

  EXEC SQL CLOSE cur2;

  EXEC SQL DISCONNECT ALL;
  return 0;
}

输出:

sizeof(item_t) = 48
   sizeof(item.int)      = 4
   sizeof(item.task)     = 40
   sizeof(item.complete) = 1

Using structure variable
------------------------
SQL error: could not convert boolean value: size mismatch, on line 80
id=1, task=task1, complete=0

SQL error: could not convert boolean value: size mismatch, on line 80
id=2, task=task2, complete=0

SQL error: could not convert boolean value: size mismatch, on line 80
id=3, task=task3, complete=0

SQL error: could not convert boolean value: size mismatch, on line 80
id=4, task=task4, complete=0

SQL error: could not convert boolean value: size mismatch, on line 80
id=5, task=task5, complete=0

SQL error: could not convert boolean value: size mismatch, on line 80
id=6, task=task6, complete=0

sizeof(int)      = 4
sizeof(task)     = 40
sizeof(complete) = 1

Using individual variables
--------------------------
id=1, task=task1, complete=1
id=2, task=task2, complete=1
id=3, task=task3, complete=1
id=4, task=task4, complete=1
id=5, task=task5, complete=0
id=6, task=task6, complete=0

1 个答案:

答案 0 :(得分:0)

问题被提出作为一个错误并由Michael Meskes修复。如果您需要解决方案,请自己动手修复。

diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 8d36484..82ab4aa 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -423,27 +423,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                case ECPGt_bool:
                    if (pval[0] == 'f' && pval[1] == '\0')
                    {
-                       if (offset == sizeof(char))
-                           *((char *) (var + offset * act_tuple)) = false;
-                       else if (offset == sizeof(int))
-                           *((int *) (var + offset * act_tuple)) = false;
-                       else
-                           ecpg_raise(lineno, ECPG_CONVERT_BOOL,
-                                      ECPG_SQLSTATE_DATATYPE_MISMATCH,
-                                      NULL);
+                       *((bool *) (var + offset * act_tuple)) = false;
                        pval++;
                        break;
                    }
                    else if (pval[0] == 't' && pval[1] == '\0')
                    {
-                       if (offset == sizeof(char))
-                           *((char *) (var + offset * act_tuple)) = true;
-                       else if (offset == sizeof(int))
-                           *((int *) (var + offset * act_tuple)) = true;
-                       else
-                           ecpg_raise(lineno, ECPG_CONVERT_BOOL,
-                                      ECPG_SQLSTATE_DATATYPE_MISMATCH,
-                                      NULL);
+                       *((bool *) (var + offset * act_tuple)) = true;
                        pval++;
                        break;
                    }
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 9e40f41..3b6eedb 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -752,18 +752,9 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                {
                    strcpy(mallocedval, "{");

-                   if (var->offset == sizeof(char))
-                       for (element = 0; element < asize; element++)
-                           sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
+                   for (element = 0; element < asize; element++)
+                                                        sprintf(mallocedval + strlen(mallocedval), "%c,", (((bool *) var->value)[element]) ? 't' : 'f');

-                   /*
-                    * this is necessary since sizeof(C++'s bool)==sizeof(int)
-                    */
-                   else if (var->offset == sizeof(int))
-                       for (element = 0; element < asize; element++)
-                           sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
-                   else
-                       ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                    }