Запрос, вызванный в typcript / javascript, возвращает синтаксическую ошибку на отметке времени $ 3, такой же запрос в PSQL выполняется без проблем. - PullRequest
0 голосов
/ 09 апреля 2019

Когда я делаю следующий запрос, все завершается нормально в psql:

-- psql
INSERT INTO public.contest (contest_id, period_id, start_ts, end_ts, contest_name, default_format, status ) 
VALUES ('VKVPA', '2019/01', timestamp '2019-01-20 08:00', 
timestamp '2019-01-20 11:00', 'description', 'EDI', 'NEW' ) RETURNING contest_key;

-- console output:
contest_key |
------------+
         17 |

(start_ts и end_ts имеют тип TIMESTAMP WITHOUT TIME ZONE) Когда я делаю то же самое в программе, это заканчиваетсяс синтаксической ошибкой:

// contest-debug.ts
import { Pool } from 'pg' ;

let pool = new Pool( {user: 'contest_owner', database: 'contest'} );

pool.query(
    "INSERT INTO public.contest (contest_id, period_id, start_ts, end_ts, contest_name, default_format, status ) "
    + "VALUES ($1, $2, timestamp $3, timestamp $4, $5, $6, 'NEW' ) RETURNING contest_key", 
    ['VKVPA', '2019/02',  '2019-01-20 08:00', '2019-01-20 11:00', 'VKV Provozni aktiv 2019/01', 'EDI']
  )
  .then( result => { 
      console.log(`New contest has number ${result.rows[0].contest_key}`);
    })
  .catch( reason => { console.log( 'Contest creation failed:', reason )});

Вывод на консоль:

Contest creation failed: { error: syntax error at or near "$3"
    at Connection.parseE (D:\dev\cav\log2any\node_modules\pg\lib\connection.js:601:11)
    at Connection.parseMessage (D:\dev\cav\log2any\node_modules\pg\lib\connection.js:398:19)
    at Socket.<anonymous> (D:\dev\cav\log2any\node_modules\pg\lib\connection.js:120:22)
    at Socket.emit (events.js:193:13)
    at addChunk (_stream_readable.js:296:12)
    at readableAddChunk (_stream_readable.js:277:11)
    at Socket.Readable.push (_stream_readable.js:232:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:150:17)
  name: 'error',
  length: 92,
  severity: 'ERROR',
  code: '42601',
  detail: undefined,
  hint: undefined,
  position: '135',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'scan.l',
  line: '1134',
  routine: 'scanner_yyerror' }

Когда я пытаюсь пройтись по функциям в модуле pg, я вижу все одинаковые правильные значения, так почему жечто вызывает ошибку синтаксиса SQL в javascript, если с самим SQL все в порядке?

К сожалению, я не знаю, где искать окончательный текст SQL, который создает модуль pg.

Что меня еще больше удивляетв том, что вчера работала одна и та же программа, сегодня нет.Я не вносил никаких изменений в саму программу, модуль tsc transpiler или pg.

ОБНОВЛЕНИЕ

Следующий код работает.Я не передавал строки меток времени в качестве параметров и вместо этого включил их непосредственно в текст запроса.По-видимому, это ошибка либо в libpq, либо в модуле javascript.

pool.query(
    "INSERT INTO public.contest (contest_id, period_id, start_ts, end_ts, contest_name, default_format, status ) "
    + "VALUES ($1, $2, timestamp '2019-02-17 08:00', timestamp '2019-02-17 11:00', $3, $4, 'NEW' ) RETURNING contest_key", 
    ['VKVPA', '2019/02',  'VKV Provozni aktiv 2019/02', 'EDI']
  )
...

1 Ответ

0 голосов
/ 09 апреля 2019

Видимо, это ошибка в документации postgres.Этот синтаксис нельзя использовать в выражениях, назначаемых столбцам, даже если строка является литеральной константой, но это явно не упоминается в руководстве (вместо этого упоминается, что другие выражения приведения типов также могут использоваться для преобразований во время выполнения).Я бы порекомендовал авторам руководства PostgreSQL быть немного более ясным в этой детали.Решение: используйте CAST ($ 3 AS TIMESTAMP) или специфичный для postgresql синтаксис $ 3 :: timestamp.

pool.query(
    "INSERT INTO public.contest (contest_id, period_id, start_ts, end_ts, contest_name, default_format, status ) "
    + "VALUES ($1, $2, CAST ($3 AS TIMESTAMP), CAST($4 AS TIMESTAMP), $5, $6, 'NEW' ) RETURNING contest_key", 
    ['VKVPA', '2019/02',  '2019-01-20 08:00', '2019-01-20 11:00', 'VKV Provozni aktiv 2019/01', 'EDI']
  )
  .then( result => { 
      console.log(`New contest has number ${result.rows[0].contest_key}`);
    })
  .catch( reason => { console.log( 'Contest creation failed:', reason )});
...