Hi

2015-08-21 7:15 GMT+02:00 Pavel Stehule <pavel.steh...@gmail.com>:

>
>
> 2015-08-20 21:16 GMT+02:00 Jim Nasby <jim.na...@bluetreble.com>:
>
>> On 8/19/15 7:22 PM, Tom Lane wrote:
>>
>>> Jim Nasby <jim.na...@bluetreble.com> writes:
>>>
>>>> Don't say "parse names for things other than tables".  Only a minority
>>>>> of the types of objects used in the database have names that meet this
>>>>> specification.
>>>>>
>>>>
>>> Really? My impression is that almost everything that's not a shared
>>>> object allows for a schema...
>>>>
>>>
>>> Tables meet this naming spec.  Columns, functions, operators, operator
>>> classes/families, collations, constraints, and conversions do not (you
>>> need more data to name them).  Schemas, databases, languages, extensions,
>>> and some other things also do not, because you need *less* data to name
>>> them.  Types also don't really meet this naming spec, because you need to
>>> contend with special cases like "int[]" or "timestamp with time zone".
>>> So this proposal doesn't seem very carefully thought-through to me,
>>> or at least the use case is much narrower than it could be.
>>>
>>> Also, if "object does not exist" isn't supposed to be an error case,
>>> what of "name is not correctly formatted"?  It seems a bit arbitrary
>>> to me to throw an error in one case but not the other.
>>>
>>
>> I think the important point here is this is *parse*_ident(). It's not
>> meant to guarantee an object actually exists, what kind of object it is, or
>> whether it's syntactically correct. It's meant only to separate an
>> identifier into it's 3 (or in some cases 2) components. If this was as
>> simple as string_to_array(foo, '.') then it'd be a bit pointless, but it's
>> obviously a lot more complex than that.
>
>
> parsing composite identifier is pretty complex - and almost all work is
> done - it just need SQL envelope only
>

here is the patch

It is really trivial - all heavy work was done done before.

Regards

Pavel

>
> Pavel
>
>
>>
>> --
>> Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX
>> Data in Trouble? Get it in Treble! http://BlueTreble.com
>>
>
>
commit 1546ec8d173c4fa91e08012af7fbfe0d64585ef0
Author: Pavel Stehule <pavel.steh...@gmail.com>
Date:   Sun Aug 23 17:43:20 2015 +0200

    initial

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 617d0b3..5d678bc 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1707,6 +1707,23 @@
       <row>
        <entry>
         <indexterm>
+         <primary>parse_ident</primary>
+        </indexterm>
+        <literal><function>parse_ident(<parameter>qualified_identifier</parameter> <type>text</type>,
+        OUT <parameter>dbname</parameter> <type>text</type>, OUT <parameter>schemaname</parameter> <type>text</type>,
+        OUT <parameter>objectname</parameter> <type>text</type>)</function></literal>
+       </entry>
+       <entry><type>record</type></entry>
+       <entry>Split <parameter>qualified identifier</parameter> to parts <parameter>dbname</parameter>,
+        <parameter>schemaname</parameter> and <parameter>objectname</parameter>.
+       </entry>
+       <entry><literal>parse_ident('"SomeSchema".someTable')</literal></entry>
+       <entry><literal>(,SomeSchema,sometable)</literal></entry>
+      </row>
+
+      <row>
+       <entry>
+        <indexterm>
          <primary>pg_client_encoding</primary>
         </indexterm>
         <literal><function>pg_client_encoding()</function></literal>
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index c0495d9..19f87db 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -21,7 +21,9 @@
 #include <unistd.h>
 
 #include "access/sysattr.h"
+#include "access/htup_details.h"
 #include "catalog/catalog.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_type.h"
 #include "commands/dbcommands.h"
@@ -598,3 +600,59 @@ pg_column_is_updatable(PG_FUNCTION_ARGS)
 
 	PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS);
 }
+
+/*
+ * parse_ident - decompose text identifier to basic three parts
+ */
+Datum
+parse_ident(PG_FUNCTION_ARGS)
+{
+	text		*qualname = PG_GETARG_TEXT_PP(0);
+	List		*name_list;
+	RangeVar	*rv;
+	Datum		values[3];
+	bool		nulls[3];
+	TupleDesc	tupdesc;
+
+	name_list = stringToQualifiedNameList(text_to_cstring(qualname));
+	rv = makeRangeVarFromNameList(name_list);
+
+	/* Prepare result tuple desc */
+	tupdesc = CreateTemplateTupleDesc(3, false);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "dbname",
+					    TEXTOID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "schemaname",
+					    TEXTOID, -1, 0);
+	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "objectname",
+					    TEXTOID, -1, 0);
+
+	BlessTupleDesc(tupdesc);
+
+	/* Fill returned values */
+	if (rv->catalogname != NULL)
+	{
+		values[0] = CStringGetTextDatum(rv->catalogname);
+		nulls[0] = false;
+	}
+	else
+		nulls[0] = true;
+
+	if (rv->schemaname != NULL)
+	{
+		values[1] = CStringGetTextDatum(rv->schemaname);
+		nulls[1] = false;
+	}
+	else
+		nulls[1] = true;
+
+	if (rv->relname != NULL)
+	{
+		values[2] = CStringGetTextDatum(rv->relname);
+		nulls[2] = false;
+	}
+	else
+		nulls[2] = true;
+
+	PG_RETURN_DATUM(HeapTupleGetDatum(
+						heap_form_tuple(tupdesc, values, nulls)));
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index ddf7c67..68a694a 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3516,6 +3516,9 @@ DESCR("I/O");
 DATA(insert OID = 4086 (  to_regnamespace	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 4089 "2275" _null_ _null_ _null_ _null_ _null_ to_regnamespace _null_ _null_ _null_ ));
 DESCR("convert namespace name to regnamespace");
 
+DATA(insert OID = 3300 (  parse_ident		PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2249 "25" "{25,25,25,25}" "{i,o,o,o}" "{identifier,dbname,schemaname,objectname}" _null_ _null_ parse_ident _null_ _null_ _null_ ));
+DESCR("parse pattern dbname.schema.object");
+
 DATA(insert OID = 2246 ( fmgr_internal_validator PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2278 "26" _null_ _null_ _null_ _null_ _null_ fmgr_internal_validator _null_ _null_ _null_ ));
 DESCR("(internal)");
 DATA(insert OID = 2247 ( fmgr_c_validator	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2278 "26" _null_ _null_ _null_ _null_ _null_ fmgr_c_validator _null_ _null_ _null_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index fc1679e..0cb491d 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -495,6 +495,7 @@ extern Datum pg_typeof(PG_FUNCTION_ARGS);
 extern Datum pg_collation_for(PG_FUNCTION_ARGS);
 extern Datum pg_relation_is_updatable(PG_FUNCTION_ARGS);
 extern Datum pg_column_is_updatable(PG_FUNCTION_ARGS);
+extern Datum parse_ident(PG_FUNCTION_ARGS);
 
 /* oid.c */
 extern Datum oidin(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/name.out b/src/test/regress/expected/name.out
index b359d52..662633f 100644
--- a/src/test/regress/expected/name.out
+++ b/src/test/regress/expected/name.out
@@ -124,3 +124,14 @@ SELECT '' AS two, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*asdf.*';
 (2 rows)
 
 DROP TABLE NAME_TBL;
+DO $$
+DECLARE r record;
+BEGIN
+  r := parse_ident('Schemax.Tabley');
+  RAISE NOTICE '%', format('%I.%I', r.schemaname, r.objectname);
+  r := parse_ident('"SchemaX"."TableY"');
+  RAISE NOTICE '%', format('%I.%I', r.schemaname, r.objectname);
+END;
+$$;
+NOTICE:  schemax.tabley
+NOTICE:  "SchemaX"."TableY"
diff --git a/src/test/regress/sql/name.sql b/src/test/regress/sql/name.sql
index 1c7a671..964ecf2 100644
--- a/src/test/regress/sql/name.sql
+++ b/src/test/regress/sql/name.sql
@@ -52,3 +52,13 @@ SELECT '' AS three, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '[0-9]';
 SELECT '' AS two, c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*asdf.*';
 
 DROP TABLE NAME_TBL;
+
+DO $$
+DECLARE r record;
+BEGIN
+  r := parse_ident('Schemax.Tabley');
+  RAISE NOTICE '%', format('%I.%I', r.schemaname, r.objectname);
+  r := parse_ident('"SchemaX"."TableY"');
+  RAISE NOTICE '%', format('%I.%I', r.schemaname, r.objectname);
+END;
+$$;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to