@@ -3121,10 +3121,150 @@ pgsetdefport(PyObject * self, PyObject * args)
31213121}
31223122#endif /* DEFAULT_VARS */
31233123
3124+ static PyObject * comma_string = NULL ;
3125+
3126+ static PyObject *
3127+ pgpy_quote_fast (PyObject * self ,PyObject * args )
3128+ {
3129+ PyObject * x ,* retval = NULL ;
3130+
3131+ if (!PyArg_ParseTuple (args ,"O:pgpy_quote_fast" ,& x ))
3132+ return NULL ;
3133+
3134+ if (x -> ob_type == & PyInt_Type || x -> ob_type == & PyLong_Type || x -> ob_type == & PyFloat_Type )
3135+ {
3136+ Py_INCREF (retval = x );
3137+ }
3138+ else if (x == Py_None )
3139+ retval = PyString_FromString ("NULL" );
3140+ else if (x -> ob_type == & PyString_Type )
3141+ {
3142+ char * in ,* out ,* ctmp ;
3143+ int i ,n ,ct ;
3144+ in = PyString_AS_STRING (x );
3145+ n = PyString_GET_SIZE (x );
3146+
3147+ for (i = ct = 0 ;i < n ;i ++ )
3148+ if (in [i ]== '\\' || in [i ]== '\'' )
3149+ ct ++ ;
3150+ ctmp = out = alloca (n + ct + 10 );
3151+ * (ctmp ++ )= '\'' ;
3152+ for (i = 0 ;i < n ;i ++ )
3153+ {
3154+ if (in [i ]== '\\' )
3155+ * (ctmp ++ )= '\\' ;
3156+ if (in [i ]== '\'' )
3157+ * (ctmp ++ )= '\'' ;
3158+ * (ctmp ++ )= in [i ];
3159+ }
3160+ * (ctmp ++ )= '\'' ;
3161+ * (ctmp ++ )= '\0' ;
3162+ retval = PyString_FromString (out );
3163+ }
3164+ else if (PySequence_Check (x ))
3165+ {
3166+ int i ,n = PySequence_Size (x );
3167+ PyObject * subout ,* subargs ,* subjoin = NULL ;
3168+
3169+ subargs = PyTuple_New (1 );
3170+ subout = PyTuple_New (n );
3171+
3172+ for (i = 0 ;i < n ;i ++ )
3173+ {
3174+ PyObject * sub = PySequence_GetItem (x ,i ),* subres ;
3175+
3176+ PyTuple_SetItem (subargs ,0 ,sub );
3177+ subres = pgpy_quote_fast (NULL ,subargs );
3178+ if (!subres )
3179+ gotoout ;
3180+
3181+ if (!PyString_Check (subres ))
3182+ {
3183+ PyObject * subres2 = PyObject_Str (subres );
3184+
3185+ if (!subres2 )
3186+ gotoout ;
3187+ Py_DECREF (subres );
3188+ subres = subres2 ;
3189+ }
3190+
3191+ PyTuple_SetItem (subout ,subres );
3192+ }
3193+
3194+ subjoin = _PyString_Join (comma_string ,subout );
3195+ if (!subjoin )
3196+ gotoout ;
3197+ retval = PyString_FromFormat ("(%s)" ,PyString_AS_STRING (subjoin ));
3198+
3199+ out :
3200+ Py_INCREF (Py_None );
3201+ PyTuple_SetItem (subargs ,0 ,Py_None );
3202+ Py_DECREF (subargs );
3203+ Py_DECREF (subout );
3204+ Py_XDECREF (subjoin );
3205+ }
3206+ else
3207+ {
3208+ retval = PyEval_CallMethod (x ,"__pg_repr__" ,"()" );
3209+ if (!retval )
3210+ {
3211+ PyErr_Format (PyExc_TypeError ,"Don't know how to quote type %s" , ((PyTypeObject * )x -> ob_type )-> tp_name );
3212+ return NULL ;
3213+ }
3214+ }
3215+
3216+ return retval ;
3217+ }
3218+
3219+ static PyObject *
3220+ pgpy_quoteparams_fast (PyObject * self ,PyObject * args )
3221+ {
3222+ PyObject * s ,* params ,* x = NULL ,* retval ;
3223+
3224+ if (!PyArg_ParseTuple ("O!O:pgpy_quoteparams_fast" ,& PyString_Type ,& s ,& params ))
3225+ return NULL ;
3226+
3227+ if (PyDict_Check (params ))
3228+ {
3229+ int i = 0 ;
3230+ PyObject * k ,* v ,* subargs ;
3231+
3232+ x = PyDict_New ();
3233+ subargs = PyTuple_New (1 );
3234+ while (PyDict_Next (params ,& i ,& k ,& v ))
3235+ {
3236+ PyObject * qres ;
3237+
3238+ PyTuple_SetItem (subargs ,0 ,v );
3239+ qres = pgpy_quote_fast (NULL ,subargs );
3240+ if (!qres )
3241+ {
3242+ Py_DECREF (x );
3243+ Py_INCREF (Py_None );
3244+ PyTuple_SetItem (subargs ,0 ,Py_None );
3245+ Py_DECREF (subargs );
3246+
3247+ return NULL ;
3248+ }
3249+
3250+ PyDict_SetItem (x ,k ,qres );
3251+ Py_DECREF (qres );
3252+ }
3253+
3254+ params = x ;
3255+ }
3256+
3257+ retval = PyString_Format (s ,params );
3258+ Py_XDECREF (x );
3259+ return retval ;
3260+ }
3261+
31243262/* List of functions defined in the module */
31253263
31263264static struct PyMethodDef pg_methods []= {
31273265{"connect" , (PyCFunction )pgconnect ,3 ,connect__doc__ },
3266+ {"quote_fast" , (PyCFunction )pgpy_quote_fast ,METH_VARARGS },
3267+ {"quoteparams_fast" , (PyCFunction )pgpy_quoteparams_fast ,METH_VARARGS },
31283268
31293269#ifdef DEFAULT_VARS
31303270{"get_defhost" ,pggetdefhost ,1 ,getdefhost__doc__ },
@@ -3178,6 +3318,8 @@ init_pg(void)
31783318PyDict_SetItemString (dict ,"RESULT_DDL" ,PyInt_FromLong (RESULT_DDL ));
31793319PyDict_SetItemString (dict ,"RESULT_DQL" ,PyInt_FromLong (RESULT_DQL ));
31803320
3321+ comma_string = PyString_InternFromString ("," );
3322+
31813323#ifdef LARGE_OBJECTS
31823324/* create mode for large objects */
31833325PyDict_SetItemString (dict ,"INV_READ" ,PyInt_FromLong (INV_READ ));