node.jsdatabasepostgresqlamazon-web-servicesamazon-rds

Easy to answer "More expressions than columns" when using CURRENT_TIMESTAMP


My typescript code is trying to insert a record into an RDS cluster and it's giving me | ERROR Error saving mytable record: error:

error: INSERT has more expressions than target columns 

I believe I counted properly. To recreate the problem, this is roughly the SQL I'm running:


      const insertResult = await client.query<{
        my_id: number;
        last_updated_timestamp: Date;
      }>(
        `INSERT INTO mytable (
              f1,
              f2,
              f3,
              f4,
              f5,
              f6,
              f7,
              f8,
              f9,
              f10,
              f11,
              f12,
              f13,
              f14,
              f15,
              f16,
              f17,
              f18,
              f19,
              f20,
              last_updated_timestamp
            ) VALUES (
              $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, CURRENT_TIMESTAMP
            ) RETURNING my_id, last_updated_timestamp`,
        [
          'fvalue01',
          'fvalue02',
          'fvalue03',
          'fvalue04',
          'fvalue05,
          'fvalue06,
          'fvalue07,
          'fvalue08,
          'fvalue09,
          'fvalue10,
          'fvalue11,
          'fvalue12,
          'fvalue13,
          'fvalue14,
          'fvalue15,
          'fvalue16,
          'fvalue17,
          'fvalue18,
          'fvalue19,
          'fvalue20,
        ]

The table mytable exists and the columns my_id, f1-f20 and last_updated_timestamp exist. The my_id is a serialized autogenerate field. I just want back whatever number it generated on my result set.

I'm not sure if whoever wrote this library insisted that all fields must be fully defined as $-positional values. Similar, but smaller INSERTs are working.

My package.json has this snippet of dependencies:

  "devDependencies": {
    "@types/aws-lambda": "^8.10.146",
    "@types/jest": "^29.5.14",
    "@types/node": "^22.10.2",
    "@types/pg": "^8.11.10",
    "@typescript-eslint/eslint-plugin": "^7.1.1",
    "@typescript-eslint/parser": "^7.1.1",
    "aws-cdk": "^2.173.2",
    "esbuild": "^0.24.0",
    "eslint": "^8.57.0",
    "eslint-config-standard": "^17.1.0",
    "eslint-import-resolver-typescript": "^3.6.1",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^6.1.1",
    "gulp": "^5.0.0",
    "gulp-typescript": "^6.0.0-alpha.1",
    "jest": "^29.7.0",
    "ts-jest": "^29.2.5",
    "ts-node": "^10.9.2",
    "tsc-watch": "^6.2.1",
    "typescript": "^5.7.2"
  },
  "dependencies": {
    "@aws-sdk/client-eventbridge": "^3.709.0",
    "@aws-sdk/client-ssm": "^3.709.0",
    "aws-cdk-lib": "^2.173.2",
    "aws-lambda": "^1.0.7",
    "constructs": "^10.4.2",
    "pg": "^8.13.1",
    "source-map-support": "^0.5.21",
    "zod": "^3.24.1"
  }
}

My Node version is:

$node --version
v20.17.0

I'm under orders to not generate a Javascript timestamp but to instead rely on the Postgres/AWS/RDS generated timestamp, which I think is causing all the problems. Please suggest a way to insert a record, and get back the my_id and last_updated_timestamp.


Solution

  • I think node.js could be converting CURRENT_TIMESTAMP into a string rather than sql variable. To avoid this, you could use current_timestamp() or now() function call in the query instead which is similar to CURRENT_TIMESTAMP

    const insertResult = await client.query<{
            my_id: number;
            last_updated_timestamp: Date;
          }>(
            `INSERT INTO mytable (
                  f1,
                  f2,
                  f3,
                  f4,
                  f5,
                  f6,
                  f7,
                  f8,
                  f9,
                  f10,
                  f11,
                  f12,
                  f13,
                  f14,
                  f15,
                  f16,
                  f17,
                  f18,
                  f19,
                  f20,
                  last_updated_timestamp
                ) VALUES (
                  $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, current_timestamp()
                ) RETURNING my_id, last_updated_timestamp`,
            [
              'fvalue01',
              'fvalue02',
              'fvalue03',
              'fvalue04',
              'fvalue05',
              'fvalue06',
              'fvalue07',
              'fvalue08',
              'fvalue09',
              'fvalue10',
              'fvalue11',
              'fvalue12',
              'fvalue13',
              'fvalue14',
              'fvalue15',
              'fvalue16',
              'fvalue17',
              'fvalue18',
              'fvalue19',
              'fvalue20',
            ]