skip to Main Content

I want to generate JSON from two usual clickhouse columns and value of one such column has backslash in its containment.

First I create table

CREATE TABLE app_events.al_test (col1 String,col2 String) ENGINE = MergeTree ORDER BY col1;

Then I insert value with backslash , I double backslash to make the insert valid

INSERT INTO app_events.al_test VALUES ('value\' , 'value1')

Next I check and see that i have value ‘value’ with one backslash in it as expected.

SELECT * FROM app_events.al_test

Next I want create JSON from this values but because of single backslash is special character I need to double it but I can’t because statement become invalid. I mean to do replacement of '' to '\' I use replace function replace(J_son ,'','\') but this is not correct SQL statement this way.

SELECT 
'{'||'"'||col1||'"'||':'||'"'||col2||'"'||'}' AS J_son ,
isValidJSON(J_son),
--replace(J_son ,'','\')
FROM app_events.al_test

how to handle such problem ?

UPD.

Thank you https://stackoverflow.com/users/320615/dogbert for your reply

Can you please help with following :

Same issue but another column types

CREATE TABLE app_events.al_test ( col1 Array(String),col2 Array(String)) ENGINE = MergeTree ORDER BY tuple();

Insert data , notice we have slash in color key :

INSERT INTO app_events.al_test VALUES (['Car','Color','Year'] , ['BMW','Red\','1990']);

I need achieve single json object which I can you as dict for separate column population ( for example I will have separate Car and Color columns which will be populated based on JSONExtractString(JSON,’Car’) and JSONExtractString(JSON,’Color’) )

How I had achieved this :

SELECT 
SUBSTRING( 
'{'||arrayStringConcat(arrayMap((k,v) -> ('"'||k||'"'||':'||'"'||v||'"'),col1,col2))||'}'||',' AS J_son,
1,
LENGTH(J_son)-1) AS JS_ON,
isValidJSON(JS_ON)
from
app_events.al_test

Script above generates correct JSON object if we had not backslash in one of values
How to handle this by using mechanism that you mentioned ?

2

Answers


  1. Chosen as BEST ANSWER

    Can be achieved following way

     SELECT toJSONString(mapFromArrays(col1, col2)) as json FROM app_events.al_test
    

  2. There is no need to do manual escaping. Create a map of col1 -> col2 using map(col1, col2) and then pass that to toJSONString:

    :) select toJSONString(map(col1, col2)) as json, isValidJSON(json) from al_test;
    
    SELECT
        toJSONString(map(col1, col2)) AS json,
        isValidJSON(json)
    FROM al_test
    
       ┌─json─────────────────┬─isValidJSON(json)─┐
    1. │ {"value\":"value1"} │                 1 │
       └──────────────────────┴───────────────────┘
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search