Browse Source

feat: implement JSON_EXTRACT for mssql, mysql, pg

pull/9532/head
Verhille 2 months ago
parent
commit
cb77f071a0
  1. 15
      packages/nocodb/src/db/functionMappings/mssql.ts
  2. 11
      packages/nocodb/src/db/functionMappings/mysql.ts
  3. 27
      packages/nocodb/src/db/functionMappings/pg.ts

15
packages/nocodb/src/db/functionMappings/mssql.ts

@ -127,7 +127,7 @@ const mssql = {
FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace( FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace(
/["']/g, /["']/g,
'', '',
)}, )},
${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${ ${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${
(await fn(pt.arguments[0])).builder (await fn(pt.arguments[0])).builder
}), 'yyyy-MM-dd HH:mm:ss') }), 'yyyy-MM-dd HH:mm:ss')
@ -135,7 +135,7 @@ const mssql = {
FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace( FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace(
/["']/g, /["']/g,
'', '',
)}, )},
${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${ ${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${
(await fn(pt.arguments[0])).builder (await fn(pt.arguments[0])).builder
}), 'yyyy-MM-dd') }), 'yyyy-MM-dd')
@ -209,6 +209,17 @@ const mssql = {
), ),
}; };
}, },
JSON_EXTRACT: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
return {
builder: knex.raw(
`CASE WHEN ISJSON(${
(await fn(pt.arguments[0])).builder
}) = 1 THEN JSON_VALUE(${(await fn(pt.arguments[0])).builder}, ${
(await fn(pt.arguments[1])).builder
}) ELSE NULL END${colAlias}`,
),
};
},
}; };
export default mssql; export default mssql;

11
packages/nocodb/src/db/functionMappings/mysql.ts

@ -171,6 +171,17 @@ END) ${colAlias}`,
), ),
}; };
}, },
JSON_EXTRACT: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
return {
builder: knex.raw(
`CASE WHEN JSON_VALID(${
(await fn(pt.arguments[0])).builder
}) = 1 THEN JSON_EXTRACT(${(await fn(pt.arguments[0])).builder}, ${
(await fn(pt.arguments[1])).builder
}) ELSE NULL END${colAlias}`,
),
};
},
}; };
export default mysql2; export default mysql2;

27
packages/nocodb/src/db/functionMappings/pg.ts

@ -60,7 +60,7 @@ const pg = {
builder: knex.raw( builder: knex.raw(
`(${(await fn(pt.arguments[0])).builder})${ `(${(await fn(pt.arguments[0])).builder})${
pt.arguments[0].dataType !== FormulaDataTypes.DATE ? '::DATE' : '' pt.arguments[0].dataType !== FormulaDataTypes.DATE ? '::DATE' : ''
} + (${(await fn(pt.arguments[1])).builder} || } + (${(await fn(pt.arguments[1])).builder} ||
'${String((await fn(pt.arguments[2])).builder).replace( '${String((await fn(pt.arguments[2])).builder).replace(
/["']/g, /["']/g,
'', '',
@ -94,17 +94,17 @@ const pg = {
break; break;
case 'month': case 'month':
sql = `( sql = `(
DATE_PART('year', ${datetime_expr1}::TIMESTAMP) - DATE_PART('year', ${datetime_expr1}::TIMESTAMP) -
DATE_PART('year', ${datetime_expr2}::TIMESTAMP) DATE_PART('year', ${datetime_expr2}::TIMESTAMP)
) * 12 + ( ) * 12 + (
DATE_PART('month', ${datetime_expr1}::TIMESTAMP) - DATE_PART('month', ${datetime_expr1}::TIMESTAMP) -
DATE_PART('month', ${datetime_expr2}::TIMESTAMP) DATE_PART('month', ${datetime_expr2}::TIMESTAMP)
)`; )`;
break; break;
case 'quarter': case 'quarter':
sql = `((EXTRACT(QUARTER FROM ${datetime_expr1}::TIMESTAMP) + sql = `((EXTRACT(QUARTER FROM ${datetime_expr1}::TIMESTAMP) +
DATE_PART('year', AGE(${datetime_expr1}, '1900/01/01')) * 4) - 1) - DATE_PART('year', AGE(${datetime_expr1}, '1900/01/01')) * 4) - 1) -
((EXTRACT(QUARTER FROM ${datetime_expr2}::TIMESTAMP) + ((EXTRACT(QUARTER FROM ${datetime_expr2}::TIMESTAMP) +
DATE_PART('year', AGE(${datetime_expr2}, '1900/01/01')) * 4) - 1)`; DATE_PART('year', AGE(${datetime_expr2}, '1900/01/01')) * 4) - 1)`;
break; break;
case 'year': case 'year':
@ -305,7 +305,7 @@ const pg = {
return { return {
builder: knex.raw( builder: knex.raw(
`CASE `CASE
WHEN ${value} IS NULL OR REGEXP_REPLACE(${value}::TEXT, '[^\\d.]+', '', 'g') IN ('.', '') OR LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^.]+', '', 'g')) > 1 THEN NULL WHEN ${value} IS NULL OR REGEXP_REPLACE(${value}::TEXT, '[^\\d.]+', '', 'g') IN ('.', '') OR LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^.]+', '', 'g')) > 1 THEN NULL
WHEN LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^%]', '','g')) > 0 THEN POW(-1, LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^-]','', 'g'))) * (REGEXP_REPLACE(${value}::TEXT, '[^\\d.]+', '', 'g'))::NUMERIC / 100 WHEN LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^%]', '','g')) > 0 THEN POW(-1, LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^-]','', 'g'))) * (REGEXP_REPLACE(${value}::TEXT, '[^\\d.]+', '', 'g'))::NUMERIC / 100
ELSE POW(-1, LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^-]', '', 'g'))) * (REGEXP_REPLACE(${value}::TEXT, '[^\\d.]+', '', 'g'))::NUMERIC ELSE POW(-1, LENGTH(REGEXP_REPLACE(${value}::TEXT, '[^-]', '', 'g'))) * (REGEXP_REPLACE(${value}::TEXT, '[^\\d.]+', '', 'g'))::NUMERIC
@ -359,6 +359,19 @@ END ${colAlias}`,
), ),
}; };
}, },
JSON_EXTRACT: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
return {
builder: knex.raw(
`CASE WHEN (${
(await fn(pt.arguments[0])).builder
})::jsonb IS NOT NULL THEN (${
(await fn(pt.arguments[0])).builder
})::jsonb #> ${
(await fn(pt.arguments[1])).builder
} ELSE NULL END${colAlias}`,
),
};
},
}; };
export default pg; export default pg;

Loading…
Cancel
Save