Postgres: QueryFailedError: type "http_response" does not exist. Unable to call HTTP function as a custom user - sql

I was trying out supabase + nestjs REST API. But for some weird reasons, HTTP trigger is not working.
We wanted to call our API end point whenever INSERT | UPDATE | DELETE operations happen in the table.
We looked into supabase webhook, but since it is still in alpha, we could not use it.
So we thought of using Postgres HTTP extension
Here's the step which i have followed.
create user api_gateway with password 'dummypassword';
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO api_gateway;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO api_gateway;
GRANT USAGE ON SCHEMA public TO api_gateway;
GRANT all ON SCHEMA net TO api_gateway;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO api_gateway;
grant usage ON schema extensions TO api_gateway;
Then i created a table in public schema as follows
create table test(
id uuid PRIMARY KEY not null DEFAULT uuid_generate_v4(),
created_at timestamp with time zone default current_timestamp not null,
name varchar(50)
);
Then i created trigger in following format
CREATE OR REPLACE FUNCTION public.test_post()
returns trigger as $$
declare hres http_response;
declare trigger_payload jsonb;
begin
trigger_payload = jsonb_build_object(
'old_record', OLD,
'record', NEW,
'type', TG_OP,
'table', TG_TABLE_NAME,
'schema', TG_TABLE_SCHEMA
);
select * into hres from http(
(
'POST',
'my rest endpoing',
ARRAY[
http_header('Authorization', concat('Bearer ', 'my token')),
http_header('Content-Type', 'application/json')
],
trigger_payload,
trigger_payload
)::http_request
);
return new;
end;
$$ language plpgsql security definer;
DROP TRIGGER IF EXISTS ON_CREATE_test on "public"."test";
CREATE TRIGGER ON_CREATE_test
AFTER INSERT ON public.test
FOR EACH ROW EXECUTE PROCEDURE public.test_post();
Then i ran the following query
GRANT ALL ON FUNCTION public.publish_to_pubsub() TO api_gateway;
Now, when i manually insert a row into the Test table from supabase dashboard, the trigger executes and the REST api request is made.
But when i connect to supabase from nestjs (using type orm module, api_gateway as user) and make a post request to insert a row into test table, i get following error.
QueryFailedError: type "http_response" does not exist
Detailed log
{
length: 721,
severity: 'ERROR',
code: '42704',
detail: undefined,
hint: undefined,
position: undefined,
internalPosition: '16',
internalQuery: '\n' +
'\n' +
'declare hres http_response;\n' +
'declare trigger_payload jsonb;\n' +
'\n' +
'begin\n' +
' trigger_payload = jsonb_build_object(\n' +
" 'old_record', OLD,\n" +
" 'record', NEW,\n" +
" 'type', TG_OP,\n" +
" 'table', TG_TABLE_NAME,\n" +
" 'schema', TG_TABLE_SCHEMA\n" +
' );\n' +
'\n' +
' select * into hres from http(\n' +
' (\n' +
" 'POST',\n" +
" 'https://api***********************************',\n" +
' ARRAY[\n' +
" http_header('Authorization', concat('Bearer ', '')),\n" +
" http_header('Content-Type', 'application/json')\n" +
' ],\n' +
' trigger_payload,\n' +
' trigger_payload\n' +
' )::http_request\n' +
' );\n' +
'\n' +
' return new;\n' +
'end;\n',
where: 'compilation of PL/pgSQL function "test_post" near line 3',
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_type.c',
line: '270',
routine: 'typenameType'
}
Not really sure what the issue is. I am happy to provide any additional information.

Related

How to use JSON_EXTRACT without having a key name?

how do I extract value frm key "Nome" from JSON using JSON_EXTRACT in google bigquery?
I cannot use the key 135 in the query because it is dynamic (Like this JSON_EXTRACT(vista, '$.Agencia.135.Nome'))
How to use JSON_EXTRACT without having a key '135' name?
JSON Record Sample:
{
"Campanha": "Campanha A",
"Ad": "Ad A",
"Agencia": {
"135": {
"Celular": ".",
"Codigo": "135",
"CodigoPai": "105",
"DDD": "00",
"Email": "email-A#email.com",
"Nome": "Nome A",
"Fone": "00 0000.0000",
"Fone2": ".",
"Foto": "foto-A.jpg"
}
}
}
Not sure if your json is formatted correctly. Is the key '135' an array? If so, format it properly and you can access it as the example below:
SELECT JSON_EXTRACT(json_text, '$.Agencia.135[1]') AS nome
FROM UNNEST([
'{"Agencia":{"135":[{"Codigo":"135"},{"Nome":"Nome A"}]}}'
]) AS json_text;
That would give you:
[
{
"nome": "{\"Nome\":\"Nome A\"}"
}
]
For more references about the JSON_EXTRACT: https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#json_extract
Use below approach
execute immediate (
select string_agg("select " || key || ''' key
, JSON_EXTRACT_SCALAR(vista, '$.Agencia.''' || key || '''.Nome') AS Nome
from `project.dataset.table`''', " union all ")
from `project.dataset.table`, unnest(regexp_extract_all(regexp_replace(JSON_EXTRACT(vista, '$.Agencia'), r':{.*?}+', ''), r'"(.*?)"')) key
);
If applied to sample data in your question - output is
Also, depends on your use case - you might try below option too
execute immediate (
select 'select * from (' || string_agg("select " || key || ''' key
, JSON_EXTRACT_SCALAR(vista, '$.Agencia.''' || key || '''.Nome') AS Nome
from `project.dataset.table`''', " union all ") || ') where not Nome is null'
from `project.dataset.table`, unnest(regexp_extract_all(regexp_replace(JSON_EXTRACT(vista, '$.Agencia'), r':{.*?}+', ''), r'"(.*?)"')) key
);

How to transform jsonb object to an array of objects?

From this:
"data": {
"media_object_uuid": ["5171167e-c109-4926-9606-5212ee250e2f"]
}
to this:
"data": {
"media_object":[{"media_object_uuid": "5171167e-c109-4926-9606-5212ee250e2f"]
}
In words, I want to extract the first value of this array and set it on the new field media_object_uuid inside media_object. My approach to resolve this was:
update demo_test set data = jsonb_set(data,'{media_object_uuid}',('{"media_object": { "media_object_uuid":' || (data->"media_object_uuid"[0])::text || '}}'));
But I have in return media_object_uuid column doesn't exist
I think you need to call data->"media_object_uuid" as data->'media_oject_uuid', since in Postgres, double-quotes are used to refer to column/entity names (unless they are first encapsulated in single-quotes):
edb=# create table abc (data jsonb);
CREATE TABLE
edb=# insert into abc values ('{
edb'# "media_object_uuid": ["5171167e-c109-4926-9606-5212ee250e2f"]
edb'# }');
INSERT 0 1
edb=# select ('{"media_object": [{ "media_object_uuid":' || (data->'media_object_uuid')::text || '}]}') from abc;
?column?
-------------------------------------------------------------------------------------
{"media_object": [{ "media_object_uuid":["5171167e-c109-4926-9606-5212ee250e2f"]}]}
(1 row)
edb=# update abc set data = jsonb_set(data,'{media_object_uuid}', ('{"media_object": [{ "media_object_uuid":' || (data->'media_object_uuid')::text || '}]}')::jsonb);
UPDATE 1
edb=# select * from abc;
data
------------------------------------------------------------------------------------------------------------
{"media_object_uuid": {"media_object": [{"media_object_uuid": ["5171167e-c109-4926-9606-5212ee250e2f"]}]}}
(1 row)

Issue in Sqlite while using Node js. Like operator and parameters

So I am trying to select rows based on user input, as shown below:
db.all(
'SELECT * FROM houses WHERE location LIKE "%$input%"',
{
$input: name,
},
(error, rows) => {
res.send(rows);
}
);
However, the database responds with an undefined value. What can I do?
You are not using query parameters properly. Consider:
db.all(
"SELECT * FROM houses WHERE location LIKE '%' || ? || '%",
[name],
(error,rows) => { ... }
);
It might be slightly more efficient to concatenate the variable in the js code:
db.all(
"SELECT * FROM houses WHERE location LIKE ?",
['%' + name + '%'],
(error,rows) => { ... }
);

Create a module that implement a new fieldType in Drupal 8 with a form that containt a field image

I need create a new fieldType into a module, in the backoffice appear like exist the created fieldType, but in the fieldType I need set a two fields, a image and a url (like string), and I found a sql error when I create a new field from the current type in drupal backoffice, because I cannot found the correct file type for the image, or the way to do it.
I have the structure like this:
[module-name]/
+ src/
| + Plugin/
| | + Field/
| | | + FieldFormatter/
| | | + FieldType/
| | | + FieldWidget/
In the module file "FieldType/[module-name]Type.php" I have the function to create the schema:
/**
* {#inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
// $schema = parent::schema($field_definition);
$schema = [];
$schema['columns']['url_op'] = [
'description' => 'The url of the cropped image',
'type' => 'varchar',
'length' => 255,
];
$schema['columns']['image_op'] = [
'type' => 'managed_file',
'description' => 'The image to crope',
'upload_location' => 'public://openseadragon-int',
];
$schema['indexes']['image_op'] = ['image_op'];
return $schema;
}
The sql error is:
Ha habido un problema creando el campo Openseadragon:
Exception thrown while performing a schema update.
SQLSTATE[42000]: Syntax error or access violation: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL DEFAULT NULL COMMENT 'The image to crope', PRIMARY KEY (`entity_id`, `dele' at line 9: CREATE TABLE {node__field_openseadragon} ( `bundle` VARCHAR(128) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT 'The field instance bundle to which this row belongs, used when deleting a field instance', `deleted` TINYINT NOT NULL DEFAULT 0 COMMENT 'A boolean indicating whether this data item has been deleted', `entity_id` INT unsigned NOT NULL COMMENT 'The entity id this data is attached to', `revision_id` INT unsigned NOT NULL COMMENT 'The entity revision id this data is attached to', `langcode` VARCHAR(32) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT 'The language code for this data item.', `delta` INT unsigned NOT NULL COMMENT 'The sequence number for this data item, used for multi-value fields', `field_openseadragon_url_op` VARCHAR(255) NULL DEFAULT NULL COMMENT 'The url of the cropped image', `field_openseadragon_image_op` NULL DEFAULT NULL COMMENT 'The image to crope', PRIMARY KEY (`entity_id`, `deleted`, `delta`, `langcode`), INDEX `bundle` (`bundle`), INDEX `revision_id` (`revision_id`), INDEX `field_openseadragon_image_op` (`field_openseadragon_image_op`) ) ENGINE = InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT 'Data storage for node field field_openseadragon.'; Array ( )

Create a log note in a record through controller

I created a record of crm.lead model through controller, and I also want to upload image or file in log note.
class RequestForQuote(http.Controller):
#route('/form/sinsert', type="http", auth="public", website=True, csrf=True)
def qoute_application_process(self,**kwargs):
values = {}
for field_name, field_value in kwargs.items():
values[field_name] = field_value
internal_notes = values['comment'] + ' , ' +values['commercial_company_name'] + ", " +values['contact_address']+ ' ' +values['contact_city'] +' '+ \
values['contact_state'] +' '+values['zip'] + ', '+ values['meeting_ids']
name = values['first_name'] +' '+values['last_name']
opportunity = request.env['crm.lead'].sudo().create({'name': name ,'date_deadline':values['date'],'email_from':values['email'],
'description':internal_notes,'type':'opportunity'
})
return werkzeug.utils.redirect('/form/thankyou')
enter image description here
To create an internal note, you just need to call self.message_post:
self.message_post(body="Internal note", attachments=[('Image', self.partner_id.image)])
You can read more at mail.thread