La specifica JDBC impedisce ‘?’ dall’essere usato come operatore (al di fuori delle virgolette)?

Dalla domanda di Sam Macbeth :

C’è qualcosa nelle specifiche JDBC che permette a? essere sfuggito ed essere qualcosa di diverso da un segnaposto di parametro?

Ad esempio, Postgres ti permette di usare ? come operatore:

 SELECT * FROM tbl WHERE tbl.data ? 'abc' 

Un driver JDBC che ti consente di utilizzare? come operatore è ancora compatibile con JDBC?

Penso che sarebbe perfettamente accettabile se il driver JDBC lo consentisse ? l’operatore non deve essere visto e utilizzato così com’è, ma potrebbe 1) complicare il parser per identificare effettivamente i parametri da questo operatore e 2) potrebbe confondere le persone (e forse gli strumenti) a cui sono abituati ? solo significato parametro segnaposto.

Quindi il mio suggerimento sarebbe quello di fornire una sorta di fuga (o operatore alternativo). Tuttavia, guardando le specifiche JDBC, i driver devono utilizzare solo la syntax di escape JDBC per implementare gli escape definiti nelle specifiche JDBC (13.4.2: “La syntax di escape non è pensata per essere utilizzata per richiamare funzioni scalari definite dall’utente o specifiche del fornitore. “, anche se questo riguarda specificamente la fuga {fn ...} ).

Quindi o devi usare una via di fuga alternativa, o “infrangere” le regole (non credo che nessuno dispiacerebbe). Se vuoi una risposta più autorevole, puoi inviare la tua domanda alla mailing list jdbc-spec-discuss . Sono certo che Lance Andersen (responsabile delle specifiche JDBC) fornirà una risposta.

Modifica :

È anche interessante notare che la sezione 6.2 delle specifiche JDBC (Linee guida e requisiti) dice:

I driver devono fornire l’accesso a tutte le funzionalità implementate dall’origine dati sottostante, incluse le funzionalità che estendono l’API JDBC. L’intento è per le applicazioni che utilizzano l’API JDBC di avere accesso allo stesso set di funzionalità delle applicazioni native.

Quindi in base a ciò dovresti (non devi) supportare il ? -operatore, devi solo trovare un modo pratico per farlo.


Aggiornamento basato sulla discussione su jdbc-spec-discuss

Secondo Lance Andersen, le specifiche JDBC seguono le specifiche SQL per quanto riguarda i punti interrogativi: possono essere utilizzate solo come segnaposto di parametri nel testo della query (tranne ovviamente nei commenti e nel testo citato), come tale uso di ? come nel postgreSQL gli operatori di hstore non sarebbero consentiti. (vedi questo messaggio )

L’opzione disponibile è di fornire un alias o una fuga per l’operatore, purché ciò non sia in conflitto con i cambiamenti futuri (il che è piuttosto difficile da fare senza chiaroveggenza;). La soluzione migliore – per evitare problemi con modifiche future di JDBC – è probabilmente una fuga personalizzata.

JDBC in realtà non definisce l’escape di un venditore, ma Lance Andersen suggerisce un’uscita che è simile agli escape di JDBC: {postgres } ; l’uso del vendorname o drivername in questa escape fornirà una forma di namespacing che dovrebbe impedire il conflitto con le specifiche. (vedi questo messaggio )

Per essere in linea con gli escape di funzione JDBC “normali”, suggerirei di definire una escape che consenta di indicare la query nella domanda come:

 SELECT * FROM tbl WHERE {postgres containskey(tbl.data, 'abc')} 

Ho scelto containskey basato sul significato di ? nella documentazione di hstore . Suggerimenti simili per ?& : containsallkeys ) e per ?| : containsanykey . Per coerenza si potrebbe considerare di farlo anche per gli altri operatori di hstore.

Potresti anche decidere di sfuggire al solo punto interrogativo. Ad esempio, sfuggire con {postgres '?'} O {postgres qm} (qm per il punto interrogativo). Penso che la leggibilità sia inferiore alla mia funzione: suggerimento di fuga:

 SELECT * FROM tbl WHERE tbl.data {postgres '?'} 'abc' 

Se hai l’ultimo driver postgresql puoi usare:

 ?? 

Modifica della query originale:

 SELECT * FROM tbl WHERE tbl.data ?? 'abc' 

I dettagli sono in questa richiesta pull – https://github.com/pgjdbc/pgjdbc/pull/227 Questa modifica è stata apportata molto tempo dopo la domanda originale, ma vale la pena notare che ora c’è una risposta facile.

Non vedo nulla nelle specifiche JDBC che consentirebbe ? essere sfuggito. Praticamente tutto ciò che dice ? è:

I marcatori dei parametri, rappresentati da “?” Nella stringa SQL, vengono utilizzati per specificare i valori di input per l’istruzione che può variare in fase di esecuzione. [1]

e più tardi…

Gli ordinali dei parametri, che sono numeri interi passati al metodo setter approriate, fanno riferimento agli indicatori di parametro (“?”) Nell’istruzione, iniziando da uno. [2]

E definisce solo la syntax di escape per un piccolo insieme di funzionalità, nessuna delle quali sembra possa essere applicata a ? :

JDBC definisce la syntax di escape per quanto segue:

  • funzioni scalari
  • data e ora letterali
  • outer join
  • chiamare stored procedure
  • caratteri di escape per le clausole LIKE [3]

Nel complesso, non sembra che la specifica JDBC abbia un linguaggio molto “rigoroso” (rispetto ad alcuni documenti con specifiche W3C che devono usare e devono molto), quindi non so se un driver che ha permesso ? essere sfuggito sarebbe tecnicamente non conforms, ma probabilmente non sarebbe così-compatibile.

Non sembra nemmeno che il driver di Postgres lo consenta, come il metodo nel driver che effettivamente analizza le istruzioni SQL ? non controlla eventuali caratteri di escape .


1. Specifiche JDBC 4.1, Sezione 13.2 – L’interfaccia PreparedStatement
2. Specifiche JDBC 4.1, Sezione 13.3.2 – Impostazione dei parametri
3. Specifiche JDBC 4.1, Sezione 13.4 – Sintassi di escape