4

We use a BNF style to convey syntax for SQL statements. For a (fictitious) example:

CREATE PARSER [schema.]function  
[WITH [LANGUAGE='language']  
    [, MODE='[FENCED | UNFENCED]'  
    [, STUFF='anotherParameter']  
];

This means that you must specify a function name (with optional schema), and you may specify zero, one, two, or three other parameters. (Some of our statements have ten or more optional parameters.) This is the style we've been using for a while.

Strictly speaking, though, it's incorrect -- if you omitted LANGUAGE but wanted to specify MODE, this would tell you to write something like:

CREATE PARSER myFunctionName
WITH , MODE='FENCED';

...which isn't correct. That comma is a syntax error. Most readers can figure out what's meant, but it's a bit of s stumbling block for some.

Some of our super-precision-minded users have pointed out this problem, but they (and we) have not found a solution that preserves the overall style. Our users like the notation overall; it's just that we don't know what to do when everything in a clause can be optional. We considered something like this, but it's technically wrong in a different way as well as being ugly:

CREATE PARSER [schema.]function
[WITH [LANGUAGE='language']
  [,] [MODE='[FENCED | UNFENCED]'
  [,] [STUFF='anotherParameter']
];

After the syntax synopsis we include a table of parameters and arguments (name, description). We're therefore considering reducing the syntax synopsis to something like this:

CREATE PARSER [schema.]function
[WITH parameters];

We haven't tried that idea out on our users yet. Before we do, I'd like to find out about other options for presenting syntax information in an informative and correct way. We're not the first people to use this style of syntax but I haven't found examples of this situation to look at. What do others do?

3

The problem here is that you are conflating two separate things: the syntax for parameters in a function expression and the list of available parameters. The syntax itself is straightforward enough:

CREATE PARSER [schema.]function  
[WITH [parameter='value' [, parameter='value']+]   
];

The list of parameters is:

LANGUAGE='language'  
MODE='[FENCED | UNFENCED]'  
STUFF='anotherParameter'  

Most API documentation separates these two things, which would seem to solve your problem.

BTW, you might point out to your developers that since the parameter values are quoted, the comma is syntactically redundant. Removing it would simplify your diagram and even let you continue to conflate parameter syntax with the list of parameters if you really wanted to.

  • 1
    Oh, nice! I kept looking at that and saying "but wait, no..." and then realizing that what I was about to say doesn't apply and it is correct. (I was going to quibble with the +, thinking it should be *, but the brackets account for that, same as they do for the first parameter -- if it's not there then the entire WITH goes away.) As for quotes, numeric values aren't quoted but I failed to show any of those. Anyway, they're not going to break backward compatibility with a syntax change, but we can improve the doc. – Monica Cellio Jun 29 '17 at 14:43
  • 1
    If the quotes are not required around numerical values, then omit them from the syntax diagram and do parameter=value and then note in the parameter listing that string values must be quoted. Unquoted numeric values would not make the list of parameters ambiguous and they could drop the requirement for commas while still allowing them for backward compatibility (but that's just me being a syntax wonk). – Mark Baker Jun 29 '17 at 16:01
  • This is much cleaner than the other answer although I also had to stare at it a bit to see that it is correct. Might be a case where English is clearer than BNF. ;) ... @MarkBaker - I'm impressed that you're as good at formal languages as you are with natural ones! – Joe Jul 5 '17 at 6:08
3

Postgres tackles a similarish problem and uses ', ...' to indicate an expression is to be repeated separated by commas (e.g. https://www.postgresql.org/docs/9.5/static/sql-createfunction.html). So in their syntax you would write something like

CREATE PARSER [*schema*.]*function* [WITH 
  { LANGUAGE='*language*'
  | MODE='[FENCED|UNFENCED]'
  | STUFF='*anotherParameter*'
  } [, ...]
];

Now if the order of those statements is fixed, this solution does not quite work.

  • Oh, so that means "here's a set of parameters; choose N and comma-separate them? Thanks; I hadn't seen that before. (And no, order doesn't matter for parameters; that's the difference between parameters and (positional) arguments for us. In my example, "function" is an argument and must be in that position.) – Monica Cellio Jun 29 '17 at 0:41
  • @MonicaCellio Yeah. I found postgresql.org/docs/current/static/notation.html though it doesn't call out comma separation in particular. – walpen Jun 29 '17 at 0:46
  • Never saw that notation before. It's a great extension? to BNF. I will use it. It beats having to say something like "optional parameters are order independent." The only thing left ambiguous is: can one parameter be specified multiple times? The default assumption would be yes. – Joe Jul 5 '17 at 5:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.