1

I've noticed that after writing SQL for PostgreSQL, when I view the SQL definition later it seems the database changed the way I formatted the SQL. For example, my leading commas are moved to the back, my tabbing is altered, etc.

Is there a way to prevent this?

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
Lenny Sockman
  • 101
  • 1
  • 13
  • Do you mean table definitions and function definitions? In that case: I'm afraid you can't prevent reformatting. – wildplasser Mar 30 '15 at 23:28
  • Hi wildplasser. I'm referring to SQL definitions for functions and views. When I view the code in the editor, the formatting is different than the formatting I wrote. The commas are moved around, the indenting is a little different, etc. – Lenny Sockman Mar 30 '15 at 23:33

2 Answers2

1

That's a misunderstanding. Postgres does not "alter the format". The original SQL string is just not stored at all.

The query is parsed and rewritten and depending on the kind of query, action is taken. For instance, when you create view, the results are stored in system catalogs, mostly pg_class and pg_rewrite.

You also must be aware that all identifiers are resolved at create time of a database object, taking the current search_path and visibility into account (early binding). The same query string can mean something different later, if the environment changes in any way.

What you see later is a re-engineered version built from these entries. There are some built-in functions to help with that, but it's largely up to the client how to format reverse-engineered SQL code.

Functions are an exception (partly). The function body is passed as string and saved as is, exactly as passed, with (currently) only superficial syntax testing and validation of objects. If you want a quick way to "save" a query including its format inside Postgres, you can use a PL/pgSQL function, for instance.

The general approach is to have an independent code repository like @Mike already suggested - or not to care about the format too much.

Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
  • Thank you Erwin, that really clarified things. As you can probably tell, I'm a bit new to PostgreSQL. Would you say most developers use an independent code repository? Is this common? – Lenny Sockman Mar 31 '15 at 02:05
  • @JordanRovny: Separate repositories are common, especially in bigger projects, not least to have a timeline and snapshots etc. I also have many projects where I just take backups as code repositories "after the fact". The format you get in backups is mostly sane - better than what most human authors produce IMHO. Sometimes the code only works hand in hand with the current state of your data. It all depends. – Erwin Brandstetter Mar 31 '15 at 02:29
  • Interesting. Could you explain "format you get in backups"? I'm not sure I follow. Thanks much, – Lenny Sockman Mar 31 '15 at 02:46
  • @JordanRovny: When you backup your db in text format with [pg_dump](http://www.postgresql.org/docs/current/interactive/app-pgdump.html) (just the schema or schema and data), you get a complete set of SQL commands - in a certain format. – Erwin Brandstetter Mar 31 '15 at 03:02
  • @JordanRovny what Erwin has listed here is both a bug and a feature. Early binding is great for performance; however, it can cause problems if you expected a different behavior. For instance, rather than early binding, I would love to create a view that would use the *search_path* for priority/dominance. If I have the same table name in multiple schemas (call them *test* and *production*), I can use the same view in both (`select * from public.v_foo`), but early-binding prevents this from happening since it resolves the table in the view to a specific schema. ... – vol7ron Apr 09 '15 at 18:08
  • ... To my knowledge, the only way around this is through the use of stored procedures, which are more difficult to write (compared to standard SQL) and much more difficult to maintain. Not to mention, stored procs aren't as publicized as tables/views (e.g., in psql `\dt` and `\dv` are much more commonly used commands, `\df` exists, but is more of an afterthought when browsing database objects). – vol7ron Apr 09 '15 at 18:10
  • Interesting, @vol7ron, I never thought about that. I assume when you say stored procedures you mean PL/pgSQL functions? – Lenny Sockman Apr 09 '15 at 18:25
  • @JordanRovny correct, I was trained in Oracle (which has pl/sql), so my terminology is sometimes a crossover and incorrect. To my knowledge, I don't think pl/pgsql has stored procedure capability (this may have change as I don't get too heavy into pl/pgsql for the reasons mentioned above - mainly for triggers or maintenance functions that don't seem to change over time). However, I'm also curious if other procedure language plugins/extensions, like pl/perl, has procedure capabilities. -- I'm sure Erwin could add to this if he cared :) – vol7ron Apr 09 '15 at 18:32
  • @vol7ron: I am not sure what the (new?) question is. If there is one I suggest to start an *actual* question instead of more comments. You can always reference this one for context. – Erwin Brandstetter Apr 09 '15 at 21:24
  • @ErwinBrandstetter your confusion is that comments are being made, which I'm guessing that you didn't read and instead assume there is a new question - there isn't, only a call for expansion if you so cared to contribute – vol7ron Apr 09 '15 at 23:47
0

The only way is to store your source code in a version control system. PostgreSQL will still do what it does, but it can't alter code that's in a VCS.

However, this is not the way most people work with databases, and it will take some self-discipline to keep all your ducks in a row.

Mike Sherrill 'Cat Recall'
  • 91,602
  • 17
  • 122
  • 185
  • Hi Mike. Could I also perhaps just keep the code in separate files, edit those, and commit the changes back to the database? It seems that way I could retain my formatting and not be concerned with how IDE's display it after-the-fact. Is this common? Thanks much, – Lenny Sockman Mar 31 '15 at 00:42
  • You can keep code in separate files. For one example, I keep `create table` and `create index` statements in separate files in case I need to recover from a disaster. Data loads faster without indexes; a makefile can put the pieces together any way you like. I'm not sure I know what you mean by "commit the changes back to the database." – Mike Sherrill 'Cat Recall' Mar 31 '15 at 01:23
  • By "commit the changes back to the database" I really just mean applying any changes to the DDL code in the files back to the database. – Lenny Sockman Mar 31 '15 at 01:47
  • Well, in my experience you're better off committing to version control first, then applying the changes to the database. There are two kinds of people. (cough) Ask the question, "Where are the most recent changes to the database?" One kind of person points to the version control system. The other kind points to the "dev" database. (And those probably use Redgate software to manage the changes.) – Mike Sherrill 'Cat Recall' Mar 31 '15 at 06:09