2017-06-01 76 views
0

我实现一个函数来获取计数的估计为PostgreSQL文档这里https://wiki.postgresql.org/wiki/Count_estimate停止jOOQ剥离从SQL域字符

我使用的功能描述:

public static Field<Integer> countEstimate(final QueryPart query) { 
    final String sql = String.format("count_estimate(%s)", escape(query.toString())); 
    return field(sql(sql), PostgresDataType.INT); 
} 

它看起来直到我在查询中传递 IN子句数组字段。发生这种情况时,jOOQ从我的SQL中剥离数组花括号。例如这种java代码调用它:

final UUID[] ids = new UUID[]{UUID.randomUUID()}; 
return db.select(countEstimate(db.select(TABLE.ID) 
    .from(TABLE) 
    .where(overlaps(ids, TABLE.FILTER_IDS)))); 

结果在这两个变量sql和上述功能渲染DSL.sql(sql)

count_estimate(E'select "schema"."table"."id" 
from "schema"."table" 
where (
    ((\'{"75910f3b-83e6-41ed-bf57-085c225e0131"}\') && ("schema"."table"."filter_ids")) 
)') 

field(sql(sql), PostgresDataType.INT)呈现此:

count_estimate(E'select "schema"."table"."id" 
from "schema"."table" 
where (
    ((\'"75910f3b-83e6-41ed-bf57-085c225e0131"\') && ("schema"."table"."filter_ids")) 
)') 

有什么方法来解决这个问题,并告诉jOOQ离开我的查询单独?

(jOOQ 3.8.3,9.5.5 PG,PG驱动9.4-1203-jdbc4)

+0

你是如何实现'越狱()'?看起来你正在使用PostgreSQL特定的非标准转义序列,以'E'...'开头。为什么? –

+0

...注意'{}'可能会被剥离,因为它们在JDBC(转义序列)和jOOQ(模板)中具有含义。它们不应该在字符串文字中有含义,但是如果你在字符串文字前面加上'E'...'',jOOQ目前可能无法识别它的格式。 –

+0

嗨卢卡斯,谢谢你解释为什么'{}'被剥夺。 在这种情况下'escape'被实现为: 'private static String escape(final String val){ return“E'”+ val.replace(“\\”,“\\\\”)。replace (“'”,“\\'”)+“'”; }' 我使用'E'...''版本的引用而不是'$$',因为上面的转换应该总是在PG解释字符串后映射回原始查询,无论该查询,但我看不出如何安全地从查询中以一种比仍然正确执行的方式逃避'$$'(或'$ foo $'等)。 –

回答

0

原来只剥去'{}'风格阵列。更换与

DSL.array(Arrays.stream(ids) 
    .map(UUID::toString) 
    .collect(Collectors.toList()) 
    .toArray(new String[0])) 
    .cast(PostgresDataType.UUID.getArrayDataType() 

导致它呈现cast(array[\'75910f3b-83e6-41ed-bf57-085c225e0131\'] as uuid[])转动UUID[]到SQL从

DSL.val(ids) 

代码防止其被剥夺