PostgreSQL не возвращает полный ответ при ошибке - PullRequest
0 голосов
/ 23 июня 2018

У меня возникает проблема, которая возникает при выполнении запроса, который приводит к ошибке.

Например, если я выполню следующий запрос

SELECT * FROM users WHERE account_id=1;

У таблицы пользователей нет столбца account_id.

Правильное сообщение об ошибке возвращает:

 00000000  45 00 00 00 6e 53 45 52  52 4f 52 00 56 45 52 52  |E...nSERROR.VERR|
 00000010  4f 52 00 43 34 32 37 30  33 00 4d 63 6f 6c 75 6d  |OR.C42703.Mcolum|
 00000020  6e 20 22 61 63 63 6f 75  6e 74 5f 69 64 22 20 64  |n "account_id" d|
 00000030  6f 65 73 20 6e 6f 74 20  65 78 69 73 74 00 50 32  |oes not exist.P2|
 00000040  37 00 46 70 61 72 73 65  5f 72 65 6c 61 74 69 6f  |7.Fparse_relatio|
 00000050  6e 2e 63 00 4c 33 32 39  33 00 52 65 72 72 6f 72  |n.c.L3293.Rerror|
 00000060  4d 69 73 73 69 6e 67 43  6f 6c 75 6d 6e 00 00 5a  |MissingColumn..Z|
 00000070  00 00 00 05 49                                    |....I|

Обратите внимание на окончание ответа.

Но время от времени я получаю следующий ответ от PostgreSQL.

 00000000  45 00 00 00 6e 53 45 52  52 4f 52 00 56 45 52 52  |E...nSERROR.VERR|
 00000010  4f 52 00 43 34 32 37 30  33 00 4d 63 6f 6c 75 6d  |OR.C42703.Mcolum|
 00000020  6e 20 22 61 63 63 6f 75  6e 74 5f 69 64 22 20 64  |n "account_id" d|
 00000030  6f 65 73 20 6e 6f 74 20  65 78 69 73 74 00 50 32  |oes not exist.P2|
 00000040  37 00 46 70 61 72 73 65  5f 72 65 6c 61 74 69 6f  |7.Fparse_relatio|
 00000050  6e 2e 63 00 4c 33 32 39  33 00 52 65 72 72 6f 72  |n.c.L3293.Rerror|
 00000060  4d 69 73 73 69 6e 67 43  6f 6c 75 6d 6e 00 00     |MissingColumn..|

И тогда клиенту не удается проанализировать ответ, потому что ему не хватает окончания.

Я что-то не так делаю, или это, возможно, ошибка в PostgreSQL?

Я получаю ответ от PostgreSQL в сети Голанга. Коннект через Read ()

Мысли

Скрипт для создания таблицы:

 DROP TABLE IF EXISTS ready.public.users;

 CREATE TABLE ready.public.users
 (
   user_id             UUID             NOT NULL,
   email               VARCHAR(325)     NOT NULL,
   password            VARCHAR(2000)    NULL,
   first_name          VARCHAR(200)     NULL,
   last_name           VARCHAR(200)     NULL,
   global_permissions  BIGINT DEFAULT 1 NOT NULL,
   is_system           BOOLEAN          NOT NULL DEFAULT false,
   is_device_only      BOOLEAN          NOT NULL DEFAULT false,
   date_created        TIMESTAMP        NOT NULL,
   date_updated        TIMESTAMP        NULL,
   date_last_logged_in TIMESTAMP        NULL,
   date_last_seen      TIMESTAMP        NULL
 );

Код, который у меня есть в моей библиотеке Голанга.

 rConn.Write(buf.Bytes())

 data := make([]byte, 2048)
 n, err := rConn.Read(data)
 data = data[:n]
 if err != nil {
    if err != io.EOF {
        panic(err)
    } else {
        log.Printf("received err: %v", err)
    }
 }

Значение buf.Bytes () равно:

 00000000  50 00 00 00 2e 00 53 45  4c 45 43 54 20 2a 20 46  |P.....SELECT * F|
 00000010  52 4f 4d 20 75 73 65 72  73 20 57 48 45 52 45 20  |ROM users WHERE |
 00000020  61 63 63 6f 75 6e 74 5f  69 64 3d 31 00 00 00 42  |account_id=1...B|
 00000030  00 00 00 0c 00 00 00 00  00 00 00 00 44 00 00 00  |............D...|
 00000040  06 50 00 45 00 00 00 09  00 00 00 01 f6 53 00 00  |.P.E.........S..|
 00000050  00 04                                             |..|

Изменение моего кода для чтения ответа от postgresql на это все равно приводит к тому же самому ответу от сервера.

 rBuf := &bytes.Buffer{}
 for {
    data := make([]byte, 256)
    n, err := rConn.Read(data)
    if err != nil {
        panic(err)
    }
    rBuf.Write(data[:n])
    if n < 256 {
        break
    }
 }
 go log.Printf("received:\n%v", hex.Dump(rBuf.Bytes()))

1 Ответ

0 голосов
/ 24 июня 2018

Ударяется ли по panic и печатает ли сообщение об ошибке? Вырвалось ли оно из цикла, прежде чем закончить чтение?

В разделе «измененный код» вы паникуете даже по io.EOF и в этом случае вы ничего не делаете с прочитанными байтами. Попробуйте удалить panic и использовать прочитанные байты перед обработкой ошибок (как вы были во фрагменте «перед») и выполнять цикл до тех пор, пока не получите ошибку чтения. Я бы хотя бы хотел выяснить / проверить:

buf := new(bytes.Buffer)
for {
    data := make([]byte, 2048)
    n, err := rConn.Read(data)
    if n > 0 {
        buf.Write(data[:n])
    }
    if err != nil {
        log.Printf("Error reading from connection: %s\n", err)
        break
    }
}
log.Printf("Received: %s\n", buf.String())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...